forked from qt-creator/qt-creator
		
	
		
			
	
	
		
			270 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			270 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								**
							 | 
						||
| 
								 | 
							
								** Copyright (C) 2021 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 "mockimagecachestorage.h"
							 | 
						||
| 
								 | 
							
								#include "mocktimestampprovider.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <synchronousimagecache.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MATCHER_P(IsIcon, icon, std::string(negation ? "isn't " : "is ") + PrintToString(icon))
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    const QIcon &other = arg;
							 | 
						||
| 
								 | 
							
								    return icon.availableSizes() == other.availableSizes();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class SynchronousImageCache : public testing::Test
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    SynchronousImageCache()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(Sqlite::TimeStamp{123}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage, fetchImage(Eq("/path/to/Component.qml"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{image1, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                fetchImage(Eq("/path/to/Component.qml+extraId1"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{image2, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage, fetchSmallImage(Eq("/path/to/Component.qml"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(
							 | 
						||
| 
								 | 
							
								                Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{smallImage1, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                fetchSmallImage(Eq("/path/to/Component.qml+extraId1"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(
							 | 
						||
| 
								 | 
							
								                Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{smallImage2, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage, fetchIcon(Eq("/path/to/Component.qml"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::IconEntry{icon1, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                fetchIcon(Eq("/path/to/Component.qml+extraId1"), Eq(Sqlite::TimeStamp{123})))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::IconEntry{icon2, true}));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockCollector, createImage(Eq("/path/to/Component.qml"), Eq("extraId1"), _))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(std::make_pair(image3, smallImage3)));
							 | 
						||
| 
								 | 
							
								        ON_CALL(mockCollector, createIcon(Eq("/path/to/Component.qml"), Eq("extraId1"), _))
							 | 
						||
| 
								 | 
							
								            .WillByDefault(Return(icon3));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    NiceMock<MockFunction<void(const QImage &image)>> mockCaptureCallback;
							 | 
						||
| 
								 | 
							
								    NiceMock<MockImageCacheStorage> mockStorage;
							 | 
						||
| 
								 | 
							
								    NiceMock<ImageCacheCollectorMock> mockCollector;
							 | 
						||
| 
								 | 
							
								    NiceMock<MockTimeStampProvider> mockTimeStampProvider;
							 | 
						||
| 
								 | 
							
								    QmlDesigner::SynchronousImageCache cache{mockStorage, mockTimeStampProvider, mockCollector};
							 | 
						||
| 
								 | 
							
								    QImage image1{1, 1, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QImage image2{2, 2, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QImage image3{3, 3, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QImage smallImage1{1, 1, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QImage smallImage2{2, 1, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QImage smallImage3{3, 1, QImage::Format_ARGB32};
							 | 
						||
| 
								 | 
							
								    QIcon icon1{QPixmap::fromImage(image1)};
							 | 
						||
| 
								 | 
							
								    QIcon icon2{QPixmap::fromImage(image2)};
							 | 
						||
| 
								 | 
							
								    QIcon icon3{QPixmap::fromImage(image3)};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetImageFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto image = cache.image("/path/to/Component.qml");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, image1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetImageWithExtraIdFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto image = cache.image("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, image2);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetImageWithOutdatedTimeStampFromCollector)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto image = cache.image("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, image3);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetImageWithOutdatedTimeStampStored)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                storeImage(Eq("/path/to/Component.qml+extraId1"),
							 | 
						||
| 
								 | 
							
								                           Eq(Sqlite::TimeStamp{124}),
							 | 
						||
| 
								 | 
							
								                           Eq(image3),
							 | 
						||
| 
								 | 
							
								                           Eq(smallImage3)));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto image = cache.image("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetSmallImageFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto image = cache.smallImage("/path/to/Component.qml");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, smallImage1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetSmallImageWithExtraIdFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto image = cache.smallImage("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, smallImage2);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetSmallImageWithOutdatedTimeStampFromCollector)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto image = cache.smallImage("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(image, smallImage3);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetSmallImageWithOutdatedTimeStampStored)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                storeImage(Eq("/path/to/Component.qml+extraId1"),
							 | 
						||
| 
								 | 
							
								                           Eq(Sqlite::TimeStamp{124}),
							 | 
						||
| 
								 | 
							
								                           Eq(image3),
							 | 
						||
| 
								 | 
							
								                           Eq(smallImage3)));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto image = cache.smallImage("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetIconFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto icon = cache.icon("/path/to/Component.qml");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(icon, IsIcon(icon1));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetIconWithExtraIdFromStorage)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    auto icon = cache.icon("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(icon, IsIcon(icon2));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetIconWithOutdatedTimeStampFromCollector)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto icon = cache.icon("/path/to/Component.qml", "extraId1");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ASSERT_THAT(icon, IsIcon(icon3));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, GetIconWithOutdatedTimeStampStored)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    using QmlDesigner::ImageCache::FontCollectorSizesAuxiliaryData;
							 | 
						||
| 
								 | 
							
								    std::vector<QSize> sizes{{20, 11}};
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockStorage,
							 | 
						||
| 
								 | 
							
								                storeIcon(Eq("/path/to/Component.qml+extraId1"),
							 | 
						||
| 
								 | 
							
								                          Eq(Sqlite::TimeStamp{124}),
							 | 
						||
| 
								 | 
							
								                          IsIcon(icon3)));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto icon = cache.icon("/path/to/Component.qml",
							 | 
						||
| 
								 | 
							
								                           "extraId1",
							 | 
						||
| 
								 | 
							
								                           FontCollectorSizesAuxiliaryData{sizes, "color"});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, IconCallsCollectorWithAuxiliaryData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    using QmlDesigner::ImageCache::FontCollectorSizesAuxiliaryData;
							 | 
						||
| 
								 | 
							
								    std::vector<QSize> sizes{{20, 11}};
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockCollector,
							 | 
						||
| 
								 | 
							
								                createIcon(Eq("/path/to/Component.qml"),
							 | 
						||
| 
								 | 
							
								                           Eq("extraId1"),
							 | 
						||
| 
								 | 
							
								                           VariantWith<FontCollectorSizesAuxiliaryData>(
							 | 
						||
| 
								 | 
							
								                               AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
							 | 
						||
| 
								 | 
							
								                                           ElementsAre(QSize{20, 11})),
							 | 
						||
| 
								 | 
							
								                                     Field(&FontCollectorSizesAuxiliaryData::colorName,
							 | 
						||
| 
								 | 
							
								                                           Eq(u"color"))))));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto icon = cache.icon("/path/to/Component.qml",
							 | 
						||
| 
								 | 
							
								                           "extraId1",
							 | 
						||
| 
								 | 
							
								                           FontCollectorSizesAuxiliaryData{sizes, "color"});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, ImageCallsCollectorWithAuxiliaryData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    using QmlDesigner::ImageCache::FontCollectorSizesAuxiliaryData;
							 | 
						||
| 
								 | 
							
								    std::vector<QSize> sizes{{20, 11}};
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockCollector,
							 | 
						||
| 
								 | 
							
								                createImage(Eq("/path/to/Component.qml"),
							 | 
						||
| 
								 | 
							
								                            Eq("extraId1"),
							 | 
						||
| 
								 | 
							
								                            VariantWith<FontCollectorSizesAuxiliaryData>(
							 | 
						||
| 
								 | 
							
								                                AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
							 | 
						||
| 
								 | 
							
								                                            ElementsAre(QSize{20, 11})),
							 | 
						||
| 
								 | 
							
								                                      Field(&FontCollectorSizesAuxiliaryData::colorName,
							 | 
						||
| 
								 | 
							
								                                            Eq(u"color"))))));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto icon = cache.image("/path/to/Component.qml",
							 | 
						||
| 
								 | 
							
								                            "extraId1",
							 | 
						||
| 
								 | 
							
								                            FontCollectorSizesAuxiliaryData{sizes, "color"});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TEST_F(SynchronousImageCache, SmallImageCallsCollectorWithAuxiliaryData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    using QmlDesigner::ImageCache::FontCollectorSizesAuxiliaryData;
							 | 
						||
| 
								 | 
							
								    std::vector<QSize> sizes{{20, 11}};
							 | 
						||
| 
								 | 
							
								    ON_CALL(mockTimeStampProvider, timeStamp(Eq("/path/to/Component.qml")))
							 | 
						||
| 
								 | 
							
								        .WillByDefault(Return(Sqlite::TimeStamp{124}));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EXPECT_CALL(mockCollector,
							 | 
						||
| 
								 | 
							
								                createImage(Eq("/path/to/Component.qml"),
							 | 
						||
| 
								 | 
							
								                            Eq("extraId1"),
							 | 
						||
| 
								 | 
							
								                            VariantWith<FontCollectorSizesAuxiliaryData>(
							 | 
						||
| 
								 | 
							
								                                AllOf(Field(&FontCollectorSizesAuxiliaryData::sizes,
							 | 
						||
| 
								 | 
							
								                                            ElementsAre(QSize{20, 11})),
							 | 
						||
| 
								 | 
							
								                                      Field(&FontCollectorSizesAuxiliaryData::colorName,
							 | 
						||
| 
								 | 
							
								                                            Eq(u"color"))))));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    auto icon = cache.smallImage("/path/to/Component.qml",
							 | 
						||
| 
								 | 
							
								                                 "extraId1",
							 | 
						||
| 
								 | 
							
								                                 FontCollectorSizesAuxiliaryData{sizes, "color"});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace
							 |