// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
// SPDX-FileCopyrightText: 2024 Arjen Hiemstra <ahiemstra@heimr.nl>
//
// This file is automatically generated from autotest.cpp.j2.
// To regenerate, run `tools/propertygenerator/generate_properties.py`.

#include <QtTest>

#include <properties/StylePropertyGroup.h>

#include "CreateTestInstances.h"

using namespace Union::Properties;
using namespace Qt::StringLiterals;

class TestStylePropertyGroup : public QObject
{
    Q_OBJECT
private Q_SLOTS:
    void testNull()
    {
        auto property = std::make_unique<StylePropertyGroup>();

        // A null instance should not have any values for its properties.
        QVERIFY(!property->display());
        QVERIFY(!property->layout());
        QVERIFY(!property->text());
        QVERIFY(!property->icon());
        QVERIFY(!property->background());
        QVERIFY(!property->border());
        QVERIFY(!property->outline());
        QVERIFY(!property->corners());
        QVERIFY(!property->shadow());
    }

    void testEmpty()
    {
        auto property = StylePropertyGroup::empty();

        // An empty instance should only have values that are considered "empty".
        QCOMPARE(*property->display(), *DisplayPropertyGroup::empty());
        QCOMPARE(*property->layout(), *LayoutPropertyGroup::empty());
        QCOMPARE(*property->text(), *TextPropertyGroup::empty());
        QCOMPARE(*property->icon(), *IconPropertyGroup::empty());
        QCOMPARE(*property->background(), *BackgroundPropertyGroup::empty());
        QCOMPARE(*property->border(), *BorderPropertyGroup::empty());
        QCOMPARE(*property->outline(), *OutlinePropertyGroup::empty());
        QCOMPARE(*property->corners(), *CornersPropertyGroup::empty());
        QCOMPARE(*property->shadow(), *ShadowPropertyGroup::empty());
    }

    void testHasAnyValue()
    {
        auto property = std::make_unique<StylePropertyGroup>();

        // An empty instance should not have any values for its properties.
        QVERIFY(!property->hasAnyValue());

        {
            // Assigning an empty value to a property should have no effect.
            property->setDisplay(std::make_unique<DisplayPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setDisplay(testDisplayPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setDisplay(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setLayout(std::make_unique<LayoutPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setLayout(testLayoutPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setLayout(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setText(std::make_unique<TextPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setText(testTextPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setText(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setIcon(std::make_unique<IconPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setIcon(testIconPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setIcon(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setBackground(std::make_unique<BackgroundPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setBackground(testBackgroundPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setBackground(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setBorder(std::make_unique<BorderPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setBorder(testBorderPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setBorder(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setOutline(std::make_unique<OutlinePropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setOutline(testOutlinePropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setOutline(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setCorners(std::make_unique<CornersPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setCorners(testCornersPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setCorners(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
        {
            // Assigning an empty value to a property should have no effect.
            property->setShadow(std::make_unique<ShadowPropertyGroup>());
            QVERIFY(!property->hasAnyValue());

            property->setShadow(testShadowPropertyGroupInstance());
            QVERIFY(property->hasAnyValue());

            property->setShadow(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
    }

    void testResolveProperties()
    {
        auto source = std::make_unique<StylePropertyGroup>();
        auto destination = std::make_unique<StylePropertyGroup>();

        QVERIFY(!source->hasAnyValue());
        QVERIFY(!destination->hasAnyValue());

        // Calling resolve on empty source and destination should have no effect.
        StylePropertyGroup::resolveProperties(source.get(), destination.get());

        QVERIFY(!destination->hasAnyValue());

        source->setDisplay(testDisplayPropertyGroupInstance());
        source->setLayout(testLayoutPropertyGroupInstance());
        source->setText(testTextPropertyGroupInstance());
        source->setIcon(testIconPropertyGroupInstance());
        source->setBackground(testBackgroundPropertyGroupInstance());
        source->setBorder(testBorderPropertyGroupInstance());
        source->setOutline(testOutlinePropertyGroupInstance());
        source->setCorners(testCornersPropertyGroupInstance());
        source->setShadow(testShadowPropertyGroupInstance());

        QVERIFY(source->hasAnyValue());
        QVERIFY(!destination->hasAnyValue());

        StylePropertyGroup::resolveProperties(source.get(), destination.get());

        QVERIFY(destination->hasAnyValue());

        QCOMPARE(*destination->display(), *source->display());
        QCOMPARE(*destination->layout(), *source->layout());
        QCOMPARE(*destination->text(), *source->text());
        QCOMPARE(*destination->icon(), *source->icon());
        QCOMPARE(*destination->background(), *source->background());
        QCOMPARE(*destination->border(), *source->border());
        QCOMPARE(*destination->outline(), *source->outline());
        QCOMPARE(*destination->corners(), *source->corners());
        QCOMPARE(*destination->shadow(), *source->shadow());
    }

    void testDataStream()
    {
        auto group = testStylePropertyGroupInstance();

        QByteArray data;
        QDataStream writeStream(&data, QIODevice::WriteOnly);
        writeStream << group.get();

        QCOMPARE(writeStream.status(), QDataStream::Status::Ok);
        QVERIFY(data.size() > 0);

        QDataStream readStream(data);
        auto readGroup = std::make_unique<StylePropertyGroup>();
        readStream >> readGroup;

        QCOMPARE(readStream.status(), QDataStream::Status::Ok);
        QCOMPARE(*readGroup, *group);
    }
};

QTEST_MAIN(TestStylePropertyGroup)

#include "TestStylePropertyGroup.moc"