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:
Marco Bubke
2022-07-04 19:24:54 +02:00
parent 8fbd703974
commit 936ae86598
10 changed files with 605 additions and 18 deletions

View File

@@ -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

View File

@@ -51,8 +51,7 @@ class ViewManagerData;
class QMLDESIGNERCORE_EXPORT ViewManager
{
public:
ViewManager(class AsynchronousImageCache &imageCache,
class AsynchronousImageCache &meshImageCache);
ViewManager(class AsynchronousImageCache &imageCache);
~ViewManager();
void attachRewriterView();

View File

@@ -62,9 +62,9 @@ static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg)
class ViewManagerData
{
public:
ViewManagerData(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
ViewManagerData(AsynchronousImageCache &imageCache)
: itemLibraryView(imageCache)
, propertyEditorView(meshImageCache)
, propertyEditorView(imageCache)
{}
InteractiveConnectionManager connectionManager;
@@ -95,8 +95,8 @@ static CrumbleBar *crumbleBar() {
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
}
ViewManager::ViewManager(AsynchronousImageCache &imageCache, AsynchronousImageCache &meshImageCache)
: d(std::make_unique<ViewManagerData>(imageCache, meshImageCache))
ViewManager::ViewManager(AsynchronousImageCache &imageCache)
: d(std::make_unique<ViewManagerData>(imageCache))
{
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
d->textEditorView.gotoCursorPosition(line, column);

View File

@@ -125,6 +125,7 @@ function(extend_with_qmldesigner_core target_name)
imagecache/asynchronousimagefactory.h
imagecache/imagecachecollector.cpp
imagecache/imagecachecollector.h
imagecache/imagecachedispatchcollector.h
imagecache/imagecachecollectorinterface.h
imagecache/imagecacheconnectionmanager.cpp
imagecache/imagecacheconnectionmanager.h

View File

@@ -135,8 +135,7 @@ class QmlDesignerPluginPrivate
{
public:
QmlDesignerProjectManager projectManager;
ViewManager viewManager{projectManager.asynchronousImageCache(),
projectManager.asynchronousMeshImageCache()};
ViewManager viewManager{projectManager.asynchronousImageCache()};
DocumentManager documentManager;
ShortCutManager shortCutManager;
SettingsPage settingsPage;

View File

@@ -438,6 +438,7 @@ Project {
"imagecache/imagecachecollectorinterface.h",
"imagecache/imagecacheconnectionmanager.cpp",
"imagecache/imagecacheconnectionmanager.h",
"imagecache/imagecachedispatchcollector.h,
"imagecache/imagecachegeneratorinterface.h",
"imagecache/imagecachegenerator.cpp",
"imagecache/imagecachegenerator.h",

View File

@@ -49,6 +49,7 @@
#include <imagecache/explicitimagecacheimageprovider.h>
#include <imagecache/imagecachecollector.h>
#include <imagecache/imagecacheconnectionmanager.h>
#include <imagecache/imagecachedispatchcollector.h>
#include <imagecache/imagecachegenerator.h>
#include <imagecache/imagecachestorage.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
class QmlDesignerProjectManager::ImageCacheData
@@ -109,12 +127,13 @@ public:
ImageCacheStorage<Sqlite::Database> storage{database};
ImageCacheConnectionManager connectionManager;
MeshImageCacheCollector meshImageCollector{connectionManager, QSize{300, 300}, QSize{600, 600}};
ImageCacheGenerator meshGenerator{meshImageCollector, storage};
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;
AsynchronousImageCache asynchronousImageCache{storage, nodeInstanceGenerator, timeStampProvider};
AsynchronousImageCache asynchronousMeshImageCache{storage, meshGenerator, timeStampProvider};
AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider};
};
class QmlDesignerProjectManager::PreviewImageCacheData
@@ -213,11 +232,6 @@ AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache()
return imageCacheData()->asynchronousImageCache;
}
AsynchronousImageCache &QmlDesignerProjectManager::asynchronousMeshImageCache()
{
return imageCacheData()->asynchronousMeshImageCache;
}
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)

View File

@@ -59,7 +59,6 @@ public:
void registerPreviewImageProvider(QQmlEngine *engine) const;
class AsynchronousImageCache &asynchronousImageCache();
class AsynchronousImageCache &asynchronousMeshImageCache();
private:
void editorOpened(::Core::IEditor *editor);

View File

@@ -81,6 +81,7 @@ add_qtc_test(unittest GTEST
synchronousimagecache-test.cpp
imagecachegenerator-test.cpp
imagecachestorage-test.cpp
imagecachedispatchcollector-test.cpp
sqlitedatabasemock.h
sqlitereadstatementmock.cpp sqlitereadstatementmock.h
sqlitereadwritestatementmock.cpp
@@ -191,6 +192,7 @@ extend_qtc_test(unittest
imagecache/imagecachegenerator.h
imagecache/imagecachegeneratorinterface.h
imagecache/imagecachestorage.h
imagecache/imagecachedispatchcollector.h
imagecache/imagecachestorageinterface.h
imagecache/synchronousimagecache.cpp
imagecache/timestampproviderinterface.h

View 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