forked from qt-creator/qt-creator
QmlDesigner: Add ImageCacheDispatchCollector
Instead of creating a new cache for every collector we now use a collector dispatcher which is dispatching the request to different collectors. Tsk-number: QDS-7258 Change-Id: I024622d4b757e1ff10f7cab4204d1742ef5926da Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -0,0 +1,164 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "imagecachecollectorinterface.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
template<typename CollectorEntries>
|
||||||
|
class ImageCacheDispatchCollector final : public ImageCacheCollectorInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageCacheDispatchCollector(CollectorEntries collectors)
|
||||||
|
: m_collectors{std::move(collectors)} {};
|
||||||
|
|
||||||
|
void start(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
CaptureCallback captureCallback,
|
||||||
|
AbortCallback abortCallback) override
|
||||||
|
{
|
||||||
|
std::apply(
|
||||||
|
[&](const auto &...collectors) {
|
||||||
|
dispatchStart(filePath,
|
||||||
|
state,
|
||||||
|
auxiliaryData,
|
||||||
|
std::move(captureCallback),
|
||||||
|
std::move(abortCallback),
|
||||||
|
collectors...);
|
||||||
|
},
|
||||||
|
m_collectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QImage, QImage> createImage(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData) override
|
||||||
|
{
|
||||||
|
return std::apply(
|
||||||
|
[&](const auto &...entries) {
|
||||||
|
return dispatchCreateImage(filePath, state, auxiliaryData, entries...);
|
||||||
|
},
|
||||||
|
m_collectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon createIcon(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData) override
|
||||||
|
{
|
||||||
|
return std::apply(
|
||||||
|
[&](const auto &...entries) {
|
||||||
|
return dispatchCreateIcon(filePath, state, auxiliaryData, entries...);
|
||||||
|
},
|
||||||
|
m_collectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Collector, typename... Collectors>
|
||||||
|
void dispatchStart(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
CaptureCallback captureCallback,
|
||||||
|
AbortCallback abortCallback,
|
||||||
|
const Collector &collector,
|
||||||
|
const Collectors &...collectors)
|
||||||
|
{
|
||||||
|
if (collector.first(filePath, state, auxiliaryData)) {
|
||||||
|
collector.second->start(filePath,
|
||||||
|
state,
|
||||||
|
auxiliaryData,
|
||||||
|
std::move(captureCallback),
|
||||||
|
std::move(abortCallback));
|
||||||
|
} else {
|
||||||
|
dispatchStart(filePath,
|
||||||
|
state,
|
||||||
|
auxiliaryData,
|
||||||
|
std::move(captureCallback),
|
||||||
|
std::move(abortCallback),
|
||||||
|
collectors...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispatchStart(Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const ImageCache::AuxiliaryData &,
|
||||||
|
CaptureCallback,
|
||||||
|
AbortCallback)
|
||||||
|
{
|
||||||
|
qWarning() << "ImageCacheDispatchCollector: cannot handle file type.";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Collector, typename... Collectors>
|
||||||
|
QIcon dispatchCreateIcon(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
const Collector &collector,
|
||||||
|
const Collectors &...collectors)
|
||||||
|
{
|
||||||
|
if (collector.first(filePath, state, auxiliaryData)) {
|
||||||
|
return collector.second->createIcon(filePath, state, auxiliaryData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dispatchCreateIcon(filePath, state, auxiliaryData, collectors...);
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon dispatchCreateIcon(Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const ImageCache::AuxiliaryData &)
|
||||||
|
{
|
||||||
|
qWarning() << "ImageCacheDispatchCollector: cannot handle file type.";
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Collector, typename... Collectors>
|
||||||
|
std::pair<QImage, QImage> dispatchCreateImage(Utils::SmallStringView filePath,
|
||||||
|
Utils::SmallStringView state,
|
||||||
|
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||||
|
const Collector &collector,
|
||||||
|
const Collectors &...collectors)
|
||||||
|
{
|
||||||
|
if (collector.first(filePath, state, auxiliaryData)) {
|
||||||
|
return collector.second->createImage(filePath, state, auxiliaryData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dispatchCreateImage(filePath, state, auxiliaryData, collectors...);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QImage, QImage> dispatchCreateImage(Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const ImageCache::AuxiliaryData &)
|
||||||
|
{
|
||||||
|
qWarning() << "ImageCacheDispatchCollector: cannot handle file type.";
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CollectorEntries m_collectors;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -51,8 +51,7 @@ class ViewManagerData;
|
|||||||
class QMLDESIGNERCORE_EXPORT ViewManager
|
class QMLDESIGNERCORE_EXPORT ViewManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewManager(class AsynchronousImageCache &imageCache,
|
ViewManager(class AsynchronousImageCache &imageCache);
|
||||||
class AsynchronousImageCache &meshImageCache);
|
|
||||||
~ViewManager();
|
~ViewManager();
|
||||||
|
|
||||||
void attachRewriterView();
|
void attachRewriterView();
|
||||||
|
@@ -62,9 +62,9 @@ static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg)
|
|||||||
class ViewManagerData
|
class ViewManagerData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewManagerData(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
|
ViewManagerData(AsynchronousImageCache &imageCache)
|
||||||
: itemLibraryView(imageCache)
|
: itemLibraryView(imageCache)
|
||||||
, propertyEditorView(meshImageCache)
|
, propertyEditorView(imageCache)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
InteractiveConnectionManager connectionManager;
|
InteractiveConnectionManager connectionManager;
|
||||||
@@ -95,8 +95,8 @@ static CrumbleBar *crumbleBar() {
|
|||||||
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
|
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewManager::ViewManager(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
|
ViewManager::ViewManager(AsynchronousImageCache &imageCache)
|
||||||
: d(std::make_unique<ViewManagerData>(imageCache, meshImageCache))
|
: d(std::make_unique<ViewManagerData>(imageCache))
|
||||||
{
|
{
|
||||||
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
||||||
d->textEditorView.gotoCursorPosition(line, column);
|
d->textEditorView.gotoCursorPosition(line, column);
|
||||||
|
@@ -125,6 +125,7 @@ function(extend_with_qmldesigner_core target_name)
|
|||||||
imagecache/asynchronousimagefactory.h
|
imagecache/asynchronousimagefactory.h
|
||||||
imagecache/imagecachecollector.cpp
|
imagecache/imagecachecollector.cpp
|
||||||
imagecache/imagecachecollector.h
|
imagecache/imagecachecollector.h
|
||||||
|
imagecache/imagecachedispatchcollector.h
|
||||||
imagecache/imagecachecollectorinterface.h
|
imagecache/imagecachecollectorinterface.h
|
||||||
imagecache/imagecacheconnectionmanager.cpp
|
imagecache/imagecacheconnectionmanager.cpp
|
||||||
imagecache/imagecacheconnectionmanager.h
|
imagecache/imagecacheconnectionmanager.h
|
||||||
|
@@ -135,8 +135,7 @@ class QmlDesignerPluginPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlDesignerProjectManager projectManager;
|
QmlDesignerProjectManager projectManager;
|
||||||
ViewManager viewManager{projectManager.asynchronousImageCache(),
|
ViewManager viewManager{projectManager.asynchronousImageCache()};
|
||||||
projectManager.asynchronousMeshImageCache()};
|
|
||||||
DocumentManager documentManager;
|
DocumentManager documentManager;
|
||||||
ShortCutManager shortCutManager;
|
ShortCutManager shortCutManager;
|
||||||
SettingsPage settingsPage;
|
SettingsPage settingsPage;
|
||||||
|
@@ -438,6 +438,7 @@ Project {
|
|||||||
"imagecache/imagecachecollectorinterface.h",
|
"imagecache/imagecachecollectorinterface.h",
|
||||||
"imagecache/imagecacheconnectionmanager.cpp",
|
"imagecache/imagecacheconnectionmanager.cpp",
|
||||||
"imagecache/imagecacheconnectionmanager.h",
|
"imagecache/imagecacheconnectionmanager.h",
|
||||||
|
"imagecache/imagecachedispatchcollector.h,
|
||||||
"imagecache/imagecachegeneratorinterface.h",
|
"imagecache/imagecachegeneratorinterface.h",
|
||||||
"imagecache/imagecachegenerator.cpp",
|
"imagecache/imagecachegenerator.cpp",
|
||||||
"imagecache/imagecachegenerator.h",
|
"imagecache/imagecachegenerator.h",
|
||||||
|
@@ -49,6 +49,7 @@
|
|||||||
#include <imagecache/explicitimagecacheimageprovider.h>
|
#include <imagecache/explicitimagecacheimageprovider.h>
|
||||||
#include <imagecache/imagecachecollector.h>
|
#include <imagecache/imagecachecollector.h>
|
||||||
#include <imagecache/imagecacheconnectionmanager.h>
|
#include <imagecache/imagecacheconnectionmanager.h>
|
||||||
|
#include <imagecache/imagecachedispatchcollector.h>
|
||||||
#include <imagecache/imagecachegenerator.h>
|
#include <imagecache/imagecachegenerator.h>
|
||||||
#include <imagecache/imagecachestorage.h>
|
#include <imagecache/imagecachestorage.h>
|
||||||
#include <imagecache/meshimagecachecollector.h>
|
#include <imagecache/meshimagecachecollector.h>
|
||||||
@@ -97,6 +98,23 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto makeCollecterDispatcherChain(ImageCacheCollector &nodeInstanceCollector,
|
||||||
|
MeshImageCacheCollector &meshImageCollector)
|
||||||
|
{
|
||||||
|
return std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView filePath,
|
||||||
|
[[maybe_unused]] Utils::SmallStringView state,
|
||||||
|
[[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData
|
||||||
|
&auxiliaryData) { return filePath.endsWith(".qml"); },
|
||||||
|
&nodeInstanceCollector),
|
||||||
|
std::make_pair(
|
||||||
|
[](Utils::SmallStringView filePath,
|
||||||
|
[[maybe_unused]] Utils::SmallStringView state,
|
||||||
|
[[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData &auxiliaryData) {
|
||||||
|
return filePath.endsWith(".mesh") || filePath.startsWith("#");
|
||||||
|
},
|
||||||
|
&meshImageCollector));
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class QmlDesignerProjectManager::ImageCacheData
|
class QmlDesignerProjectManager::ImageCacheData
|
||||||
@@ -109,12 +127,13 @@ public:
|
|||||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||||
ImageCacheConnectionManager connectionManager;
|
ImageCacheConnectionManager connectionManager;
|
||||||
MeshImageCacheCollector meshImageCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
MeshImageCacheCollector meshImageCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||||
ImageCacheGenerator meshGenerator{meshImageCollector, storage};
|
|
||||||
ImageCacheCollector nodeInstanceCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
ImageCacheCollector nodeInstanceCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||||
ImageCacheGenerator nodeInstanceGenerator{nodeInstanceCollector, storage};
|
ImageCacheDispatchCollector<decltype(makeCollecterDispatcherChain(nodeInstanceCollector,
|
||||||
|
meshImageCollector))>
|
||||||
|
dispatchCollector{makeCollecterDispatcherChain(nodeInstanceCollector, meshImageCollector)};
|
||||||
|
ImageCacheGenerator generator{dispatchCollector, storage};
|
||||||
TimeStampProvider timeStampProvider;
|
TimeStampProvider timeStampProvider;
|
||||||
AsynchronousImageCache asynchronousImageCache{storage, nodeInstanceGenerator, timeStampProvider};
|
AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider};
|
||||||
AsynchronousImageCache asynchronousMeshImageCache{storage, meshGenerator, timeStampProvider};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlDesignerProjectManager::PreviewImageCacheData
|
class QmlDesignerProjectManager::PreviewImageCacheData
|
||||||
@@ -213,11 +232,6 @@ AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache()
|
|||||||
return imageCacheData()->asynchronousImageCache;
|
return imageCacheData()->asynchronousImageCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsynchronousImageCache &QmlDesignerProjectManager::asynchronousMeshImageCache()
|
|
||||||
{
|
|
||||||
return imageCacheData()->asynchronousMeshImageCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
|
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
|
||||||
|
|
||||||
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)
|
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)
|
||||||
|
@@ -59,7 +59,6 @@ public:
|
|||||||
void registerPreviewImageProvider(QQmlEngine *engine) const;
|
void registerPreviewImageProvider(QQmlEngine *engine) const;
|
||||||
|
|
||||||
class AsynchronousImageCache &asynchronousImageCache();
|
class AsynchronousImageCache &asynchronousImageCache();
|
||||||
class AsynchronousImageCache &asynchronousMeshImageCache();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void editorOpened(::Core::IEditor *editor);
|
void editorOpened(::Core::IEditor *editor);
|
||||||
|
@@ -81,6 +81,7 @@ add_qtc_test(unittest GTEST
|
|||||||
synchronousimagecache-test.cpp
|
synchronousimagecache-test.cpp
|
||||||
imagecachegenerator-test.cpp
|
imagecachegenerator-test.cpp
|
||||||
imagecachestorage-test.cpp
|
imagecachestorage-test.cpp
|
||||||
|
imagecachedispatchcollector-test.cpp
|
||||||
sqlitedatabasemock.h
|
sqlitedatabasemock.h
|
||||||
sqlitereadstatementmock.cpp sqlitereadstatementmock.h
|
sqlitereadstatementmock.cpp sqlitereadstatementmock.h
|
||||||
sqlitereadwritestatementmock.cpp
|
sqlitereadwritestatementmock.cpp
|
||||||
@@ -191,6 +192,7 @@ extend_qtc_test(unittest
|
|||||||
imagecache/imagecachegenerator.h
|
imagecache/imagecachegenerator.h
|
||||||
imagecache/imagecachegeneratorinterface.h
|
imagecache/imagecachegeneratorinterface.h
|
||||||
imagecache/imagecachestorage.h
|
imagecache/imagecachestorage.h
|
||||||
|
imagecache/imagecachedispatchcollector.h
|
||||||
imagecache/imagecachestorageinterface.h
|
imagecache/imagecachestorageinterface.h
|
||||||
imagecache/synchronousimagecache.cpp
|
imagecache/synchronousimagecache.cpp
|
||||||
imagecache/timestampproviderinterface.h
|
imagecache/timestampproviderinterface.h
|
||||||
|
408
tests/unit/unittest/imagecachedispatchcollector-test.cpp
Normal file
408
tests/unit/unittest/imagecachedispatchcollector-test.cpp
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "googletest.h"
|
||||||
|
|
||||||
|
#include "imagecachecollectormock.h"
|
||||||
|
|
||||||
|
#include <imagecache/imagecachedispatchcollector.h>
|
||||||
|
#include <imagecacheauxiliarydata.h>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using QmlDesigner::ImageCache::FontCollectorSizesAuxiliaryData;
|
||||||
|
|
||||||
|
MATCHER_P(IsIcon, icon, std::string(negation ? "isn't " : "is ") + PrintToString(icon))
|
||||||
|
{
|
||||||
|
const QIcon &other = arg;
|
||||||
|
return icon.availableSizes() == other.availableSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P2(IsImage,
|
||||||
|
image,
|
||||||
|
smallImage,
|
||||||
|
std::string(negation ? "aren't " : "are ") + PrintToString(image) + " and "
|
||||||
|
+ PrintToString(smallImage))
|
||||||
|
{
|
||||||
|
const std::pair<QImage, QImage> &other = arg;
|
||||||
|
return other.first == image && other.second == smallImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImageCacheDispatchCollector : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ImageCacheDispatchCollector()
|
||||||
|
{
|
||||||
|
ON_CALL(collectorMock1, createIcon(_, _, _)).WillByDefault(Return(icon1));
|
||||||
|
ON_CALL(collectorMock2, createIcon(_, _, _)).WillByDefault(Return(icon2));
|
||||||
|
|
||||||
|
ON_CALL(collectorMock1, createImage(_, _, _))
|
||||||
|
.WillByDefault(Return(std::pair{image1, smallImage1}));
|
||||||
|
ON_CALL(collectorMock2, createImage(_, _, _))
|
||||||
|
.WillByDefault(Return(std::pair{image2, smallImage2}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<QSize> sizes{{20, 11}};
|
||||||
|
NiceMock<MockFunction<void(const QImage &, const QImage &)>> captureCallbackMock;
|
||||||
|
NiceMock<MockFunction<void(QmlDesigner::ImageCache::AbortReason)>> abortCallbackMock;
|
||||||
|
NiceMock<ImageCacheCollectorMock> collectorMock1;
|
||||||
|
NiceMock<ImageCacheCollectorMock> collectorMock2;
|
||||||
|
QImage image1{1, 1, QImage::Format_ARGB32};
|
||||||
|
QImage image2{2, 2, QImage::Format_ARGB32};
|
||||||
|
QImage smallImage1{1, 1, QImage::Format_ARGB32};
|
||||||
|
QImage smallImage2{2, 1, QImage::Format_ARGB32};
|
||||||
|
QIcon icon1{QPixmap::fromImage(image1)};
|
||||||
|
QIcon icon2{QPixmap::fromImage(image2)};
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallQmlCollectorStart)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair(
|
||||||
|
[](Utils::SmallStringView filePath,
|
||||||
|
[[maybe_unused]] Utils::SmallStringView state,
|
||||||
|
[[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData &auxiliaryData) {
|
||||||
|
Utils::SmallStringView ending = ".ui.qml";
|
||||||
|
return filePath.size() > ending.size()
|
||||||
|
&& std::equal(ending.rbegin(), ending.rend(), filePath.rbegin());
|
||||||
|
},
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair(
|
||||||
|
[](Utils::SmallStringView filePath,
|
||||||
|
[[maybe_unused]] Utils::SmallStringView state,
|
||||||
|
[[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData &auxiliaryData) {
|
||||||
|
Utils::SmallStringView ending = ".qml";
|
||||||
|
return filePath.size() > ending.size()
|
||||||
|
&& std::equal(ending.rbegin(), ending.rend(), filePath.rbegin());
|
||||||
|
},
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(captureCallbackMock, Call(_, _));
|
||||||
|
EXPECT_CALL(abortCallbackMock, Call(_));
|
||||||
|
EXPECT_CALL(collectorMock2,
|
||||||
|
start(Eq("foo.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName, Eq(u"color")))),
|
||||||
|
_,
|
||||||
|
_))
|
||||||
|
.WillRepeatedly([&](auto, auto, auto, auto captureCallback, auto abortCallback) {
|
||||||
|
captureCallback(QImage{}, QImage{});
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Abort);
|
||||||
|
});
|
||||||
|
EXPECT_CALL(collectorMock1, start(_, _, _, _, _)).Times(0);
|
||||||
|
|
||||||
|
collector.start("foo.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"},
|
||||||
|
captureCallbackMock.AsStdFunction(),
|
||||||
|
abortCallbackMock.AsStdFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallUiFileCollectorStart)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(captureCallbackMock, Call(_, _));
|
||||||
|
EXPECT_CALL(abortCallbackMock, Call(_));
|
||||||
|
EXPECT_CALL(collectorMock1,
|
||||||
|
start(Eq("foo.ui.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName, Eq(u"color")))),
|
||||||
|
_,
|
||||||
|
_))
|
||||||
|
.WillRepeatedly([&](auto, auto, auto, auto captureCallback, auto abortCallback) {
|
||||||
|
captureCallback(QImage{}, QImage{});
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Abort);
|
||||||
|
});
|
||||||
|
EXPECT_CALL(collectorMock2, start(_, _, _, _, _)).Times(0);
|
||||||
|
|
||||||
|
collector.start("foo.ui.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"},
|
||||||
|
captureCallbackMock.AsStdFunction(),
|
||||||
|
abortCallbackMock.AsStdFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, DontCallCollectorStartForUnknownFile)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock2, start(_, _, _, _, _)).Times(0);
|
||||||
|
EXPECT_CALL(collectorMock1, start(_, _, _, _, _)).Times(0);
|
||||||
|
|
||||||
|
collector.start("foo.mesh",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"},
|
||||||
|
captureCallbackMock.AsStdFunction(),
|
||||||
|
abortCallbackMock.AsStdFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallFirstCollectorCreateIcon)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto icon = collector.createIcon("foo.ui.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_THAT(icon, IsIcon(icon1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, FirstCollectorCreateIconCalls)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock1,
|
||||||
|
createIcon(Eq("foo.ui.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName,
|
||||||
|
Eq(u"color"))))));
|
||||||
|
EXPECT_CALL(collectorMock2, createIcon(_, _, _)).Times(0);
|
||||||
|
|
||||||
|
auto icon = collector.createIcon("foo.ui.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallSecondCollectorCreateIcon)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto icon = collector.createIcon("foo.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_THAT(icon, IsIcon(icon2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, SecondCollectorCreateIconCalls)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock2,
|
||||||
|
createIcon(Eq("foo.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName,
|
||||||
|
Eq(u"color"))))));
|
||||||
|
EXPECT_CALL(collectorMock1, createIcon(_, _, _)).Times(0);
|
||||||
|
|
||||||
|
auto icon = collector.createIcon("foo.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, DontCallCollectorCreateIconForUnknownFile)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto icon = collector.createIcon("foo.mesh",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_TRUE(icon.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallFirstCollectorCreateImage)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto image = collector.createImage("foo.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_THAT(image, IsImage(image1, smallImage1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, FirstCollectorCreateImageCalls)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock1,
|
||||||
|
createImage(Eq("foo.ui.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName,
|
||||||
|
Eq(u"color"))))));
|
||||||
|
EXPECT_CALL(collectorMock2, createImage(_, _, _)).Times(0);
|
||||||
|
|
||||||
|
auto icon = collector.createImage("foo.ui.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, CallSecondCollectorCreateImage)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto image = collector.createImage("foo.ui.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_THAT(image, IsImage(image2, smallImage2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, SecondCollectorCreateImageCalls)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return true; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock2,
|
||||||
|
createImage(Eq("foo.qml"),
|
||||||
|
Eq("state"),
|
||||||
|
VariantWith<FontCollectorSizesAuxiliaryData>(
|
||||||
|
AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
|
||||||
|
ElementsAre(QSize{20, 11})),
|
||||||
|
Field(&FontCollectorSizesAuxiliaryData::colorName,
|
||||||
|
Eq(u"color"))))));
|
||||||
|
EXPECT_CALL(collectorMock1, createImage(_, _, _)).Times(0);
|
||||||
|
|
||||||
|
auto icon = collector.createImage("foo.qml",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheDispatchCollector, DontCallCollectorCreateImageForUnknownFile)
|
||||||
|
{
|
||||||
|
QmlDesigner::ImageCacheDispatchCollector collector{std::make_tuple(
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock1),
|
||||||
|
std::make_pair([](Utils::SmallStringView,
|
||||||
|
Utils::SmallStringView,
|
||||||
|
const QmlDesigner::ImageCache::AuxiliaryData &) { return false; },
|
||||||
|
&collectorMock2))};
|
||||||
|
|
||||||
|
auto image = collector.createImage("foo.mesh",
|
||||||
|
"state",
|
||||||
|
FontCollectorSizesAuxiliaryData{sizes, "color", "text"});
|
||||||
|
|
||||||
|
ASSERT_TRUE(image.first.isNull() && image.second.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
Reference in New Issue
Block a user