Skip to content
Snippets Groups Projects
TestMapperForItem.cpp 8.63 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "GUI/Model/Data/MaskItems.h"
    #include "GUI/Model/Data/ProjectionItems.h"
    #include "GUI/Model/Sample/LayerItem.h"
    #include "GUI/Model/Sample/MultiLayerItem.h"
    #include "GUI/Model/Sample/SampleModel.h"
    #include "GUI/Model/Session/SessionItemUtils.h"
    #include "GUI/Model/Types/DoubleDescriptor.h"
    
    #include "Tests/GTestWrapper/google_test.h"
    
    #include <memory>
    
    
    using GUI::Session::ItemUtils::ParentRow;
    
    //! Test Widget which logs calling activity of ModelMapper
    
    class Widget {
    
            : m_onPropertyChangeCount(0)
            , m_onChildPropertyChangeCount(0)
            , m_onParentChangeCount(0)
            , m_onChildrenChangeCount(0)
    
            m_onPropertyChangeCount = 0;
            m_onChildPropertyChangeCount = 0;
            m_onParentChangeCount = 0;
            m_onChildrenChangeCount = 0;
    
            m_onAboutToRemoveChild = 0;
    
            m_reported_items.clear();
            m_reported_names.clear();
    
        void subscribe(ModelMapper* mapper, bool with_subscription = false)
        {
    
            void* caller = (with_subscription ? this : nullptr);
    
            mapper->setOnPropertyChange([this](QString name) { onPropertyChange(name); }, caller);
    
            mapper->setOnChildPropertyChange(
    
                [this](SessionItem* item, QString name) { onChildPropertyChange(item, name); }, caller);
    
            mapper->setOnParentChange([this](SessionItem* parent) { onParentChange(parent); }, caller);
    
            mapper->setOnChildrenChange([this](SessionItem*) { onChildrenChange(); }, caller);
    
            mapper->setOnAboutToRemoveChild([this](SessionItem* item) { onAboutToRemoveChild(item); },
                                            caller);
    
        void onPropertyChange(const QString& name)
        {
    
            m_reported_names.append(name);
    
            m_onPropertyChangeCount++;
        }
    
    
        void onChildPropertyChange(SessionItem* item, const QString& name)
        {
    
            m_reported_items.append(item);
            m_reported_names.append(name);
    
            m_onChildPropertyChangeCount++;
        }
    
    
        void onParentChange(SessionItem* item)
        {
    
            m_reported_items.append(item);
    
            m_onParentChangeCount++;
        }
    
    
        void onChildrenChange() { m_onChildrenChangeCount++; }
    
        void unsubscribe(ModelMapper* mapper) { mapper->unsubscribe(this); }
    
        void onAboutToRemoveChild(SessionItem* item)
        {
    
            m_reported_items.append(item);
            m_onAboutToRemoveChild++;
        }
    
    
        int m_onPropertyChangeCount;
        int m_onChildPropertyChangeCount;
        int m_onParentChangeCount;
        int m_onChildrenChangeCount;
    
        int m_onAboutToRemoveChild;
    
        QList<SessionItem*> m_reported_items;
    
        QStringList m_reported_names;
    
    class TestMapperForItem : public ::testing::Test {
    
        TestMapperForItem() : m_mapped_item(nullptr) {}
    
        void setItem(SessionItem* item, Widget* widget = nullptr, bool with_subscription = false)
    
            m_mapped_item = item;
    
            m_mapper = std::make_unique<ModelMapper>();
    
            m_mapper->setItem(item);
    
            if (widget)
                widget->subscribe(m_mapper.get(), with_subscription);
    
        SessionItem* m_mapped_item;
    
        std::unique_ptr<ModelMapper> m_mapper;
    };
    
    
    TEST_F(TestMapperForItem, initialCondition)
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE(w.m_reported_names.isEmpty());
        EXPECT_TRUE(m_mapped_item == nullptr);
        EXPECT_TRUE(!m_mapper);
    
    TEST_F(TestMapperForItem, onPropertyChange)
    
        SampleModel model;
    
        auto* multilayer = model.insertItem<MultiLayerItem>();
    
        auto* layer = multilayer->addLayer();
    
    
        // Mapper is looking on child; set property of child
    
        setItem(layer, &w);
    
        EXPECT_TRUE(m_mapped_item == layer);
    
        layer->thickness().set(1.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 1);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE((w.m_reported_names.size() == 1)
    
                    && LayerItem::isThicknessPropertyName(w.m_reported_names[0]));
    
    
        // Mapper is looking on child; set property of parent;
    
        setItem(layer, &w);
    
        EXPECT_TRUE(m_mapped_item == layer);
    
        multilayer->crossCorrLength().set(1.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE(w.m_reported_names.isEmpty());
    
    
        // Mapper is looking on parent; set property of child;
    
        setItem(multilayer, &w);
    
        EXPECT_TRUE(m_mapped_item == multilayer);
    
        layer->thickness().set(2.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 1);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE((w.m_reported_items.size() == 1) && (w.m_reported_items[0] == layer));
        EXPECT_TRUE((w.m_reported_names.size() == 1)
    
                    && LayerItem::isThicknessPropertyName(w.m_reported_names[0]));
    
    
        // Mapper is looking on parent; set property of parent;
    
        setItem(multilayer, &w);
    
        EXPECT_TRUE(m_mapped_item == multilayer);
    
        multilayer->crossCorrLength().set(2.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 1);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE((w.m_reported_names.size() == 1)
    
                    && MultiLayerItem::isCrossCorrLengthPropertyName(w.m_reported_names[0]));
    
    TEST_F(TestMapperForItem, onSiblingsChange)
    
        auto* multilayer = model.insertItem<MultiLayerItem>();
        auto* layer = model.insertItem<LayerItem>(multilayer);
    
    
        // Mapper is looking on child; adding another child to parent
    
        setItem(layer, &w);
    
        EXPECT_TRUE(m_mapped_item == layer);
    
        model.insertItem<LayerItem>(multilayer);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE(w.m_reported_names.isEmpty());
    
    TEST_F(TestMapperForItem, Subscription)
    
        auto* multilayer = model.insertItem<MultiLayerItem>();
        auto* layer = model.insertItem<LayerItem>(multilayer);
    
    
        // Mapper is looking on child; set property of child
    
        setItem(layer, &w, true);
    
        EXPECT_TRUE(m_mapped_item == layer);
    
        layer->thickness().set(1.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 1);
        EXPECT_EQ(w.m_onChildPropertyChangeCount, 0);
        EXPECT_EQ(w.m_onParentChangeCount, 0);
        EXPECT_EQ(w.m_onChildrenChangeCount, 0);
        EXPECT_TRUE(w.m_reported_items.isEmpty());
        EXPECT_TRUE((w.m_reported_names.size() == 1)
    
                    && LayerItem::isThicknessPropertyName(w.m_reported_names[0]));
    
        layer->thickness().set(2.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 2);
    
        // unsubscribe widget and check that it doesn't react on item value change
    
        w.unsubscribe(m_mapper.get());
    
        layer->thickness().set(3.0);
    
        EXPECT_EQ(w.m_onPropertyChangeCount, 2);
    
    TEST_F(TestMapperForItem, TwoWidgetsSubscription)
    
        Widget w1, w2;
        SampleModel model;
    
        auto* multilayer = model.insertItem<MultiLayerItem>();
        auto* layer = model.insertItem<LayerItem>(multilayer);
    
    
        // Mapper is looking on child; set property of child
        setItem(layer);
        w1.subscribe(m_mapper.get(), true);
        w2.subscribe(m_mapper.get(), true);
    
        EXPECT_EQ(w1.m_onPropertyChangeCount, 0);
        EXPECT_EQ(w2.m_onPropertyChangeCount, 0);
    
        layer->thickness().set(1.0);
    
        EXPECT_EQ(w1.m_onPropertyChangeCount, 1);
        EXPECT_EQ(w2.m_onPropertyChangeCount, 1);
    
    
        w1.unsubscribe(m_mapper.get());
    
        layer->thickness().set(2.0);
    
        EXPECT_EQ(w1.m_onPropertyChangeCount, 1);
        EXPECT_EQ(w2.m_onPropertyChangeCount, 2);
    
    TEST_F(TestMapperForItem, AboutToRemoveChild)
    
        auto* container = model.insertItem<ProjectionContainerItem>();
        auto* line = model.insertItem<HorizontalLineItem>(container);
    
        EXPECT_EQ(w.m_onAboutToRemoveChild, 0);
        EXPECT_EQ(w.m_reported_items.size(), 0);
    
        delete line->parent()->takeRow(line->parent()->rowOfChild(line));
    
        EXPECT_EQ(w.m_onAboutToRemoveChild, 1);
        EXPECT_EQ(w.m_reported_items.size(), 1);
        EXPECT_EQ(w.m_reported_items.back(), line);