{#
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 is the template that is used to generate tests for property classes.

REUSE-IgnoreStart
#}
// 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`.
{# REUSE-IgnoreEnd #}

#include <QtTest>

#include <properties/{{ type }}.h>

#include "CreateTestInstances.h"

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

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

        // A null instance should not have any values for its properties.
{% for property in children %}
{% if property.children %}
        QVERIFY(!property->{{ property.name }}());
{% else %}
        QVERIFY(!property->{{ property.name }}().has_value());
{% endif %}
{% endfor %}
    }

    void testEmpty()
    {
        auto property = {{ type }}::empty();

        // An empty instance should only have values that are considered "empty".
{% for property in children %}
{% if property.children %}
        QCOMPARE(*property->{{ property.name }}(), *{{ property.type }}::empty());
{% else %}
        QCOMPARE(property->{{ property.name }}().value(), emptyValue<{{ property.type }}>());
{% endif %}
{% endfor %}
    }

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

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

{% for property in children %}
{% if not property.children %}
        {
            {{ property.type }} value;
            property->set{{ property.name | ucfirst }}(value);
            QVERIFY(property->hasAnyValue());
            property->set{{ property.name | ucfirst }}(std::nullopt);
            QVERIFY(!property->hasAnyValue());
        }
{% else %}
        {
            // Assigning an empty value to a property should have no effect.
            property->set{{ property.name | ucfirst }}(std::make_unique<{{ property.type }}>());
            QVERIFY(!property->hasAnyValue());

            property->set{{ property.name | ucfirst }}(test{{ property.type }}Instance());
            QVERIFY(property->hasAnyValue());

            property->set{{ property.name | ucfirst }}(nullptr);
            QVERIFY(!property->hasAnyValue());
        }
{% endif %}
{% endfor %}
    }

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

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

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

        QVERIFY(!destination->hasAnyValue());

{% for property in children %}
{% if not property.children %}
        source->set{{ property.name | ucfirst }}({{ property.type }}{});
{% else %}
        source->set{{ property.name | ucfirst }}(test{{ property.type }}Instance());
{% endif %}
{% endfor %}

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

        {{ type }}::resolveProperties(source.get(), destination.get());

        QVERIFY(destination->hasAnyValue());

{% for property in children %}
{% if property.children %}
        QCOMPARE(*destination->{{ property.name }}(), *source->{{ property.name }}());
{% else %}
        QCOMPARE(destination->{{ property.name }}(), source->{{ property.name }}());
{% endif %}
{% endfor %}
    }

    void testDataStream()
    {
        auto group = test{{ type }}Instance();

        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<{{ type }}>();
        readStream >> readGroup;

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

QTEST_MAIN(Test{{ type }})

#include "Test{{ type }}.moc"
