/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtCore>
#include <qquicktreemodeladaptor_p.h>
#include "../shared/testmodel.h"

class tst_QQuickTreeModelAdaptor : public QObject
{
    Q_OBJECT

public:
    void compareData(int row, QQuickTreeModelAdaptor1 &tma, const QModelIndex &idx, TestModel &model, bool expanded = false);
    void compareModels(QQuickTreeModelAdaptor1 &tma, TestModel &model);
    void expandAndTest(const QModelIndex &idx, QQuickTreeModelAdaptor1 &tma, bool expandable, int expectedRowCountDifference);
    void collapseAndTest(const QModelIndex &idx, QQuickTreeModelAdaptor1 &tma, bool expandable, int expectedRowCountDifference);
    bool rowRoleWasChanged(const QSignalSpy &captured, int row, int role);

private slots:
    void initTestCase();
    void cleanup();

    void setModel();
    void modelDestroyed();
    void modelReset();

    void rootIndex();

    void dataAccess();
    void dataChange();
    void groupedDataChange();

    void expandAndCollapse_data();
    void expandAndCollapse();
    void expandAndCollapse2ndLevel();

    void layoutChange();

    void removeRows_data();
    void removeRows();

    void removeRowsChildrenAndParent();
    void removeChildrenMoveParent();
    void removeChildrenRelayoutParent();

    void insertRows_data();
    void insertRows();

    void moveRows_data();
    void moveRows();
    void moveRowsDataChanged_data();
    void moveRowsDataChanged();
    void reparentOnSameRow();
    void moveAllChildren();

    void selectionForRowRange();

    void hasChildrenEmit();
};

void tst_QQuickTreeModelAdaptor::initTestCase()
{
}

void tst_QQuickTreeModelAdaptor::cleanup()
{
}

void tst_QQuickTreeModelAdaptor::compareData(int row, QQuickTreeModelAdaptor1 &tma, const QModelIndex &modelIdx, TestModel &model, bool expanded)
{
    const QModelIndex &tmaIdx = tma.index(row);
    const int indexDepth = model.level(modelIdx) - model.level(tma.rootIndex()) - 1;
    QCOMPARE(tma.mapToModel(tmaIdx), modelIdx);
    QCOMPARE(tma.data(tmaIdx, Qt::DisplayRole).toString(), model.displayData(modelIdx));
    QCOMPARE(tma.data(tmaIdx, QQuickTreeModelAdaptor1::DepthRole).toInt(), indexDepth);
    QCOMPARE(tma.data(tmaIdx, QQuickTreeModelAdaptor1::ExpandedRole).toBool(), expanded);
    QCOMPARE(tma.data(tmaIdx, QQuickTreeModelAdaptor1::HasChildrenRole).toBool(), model.hasChildren(modelIdx));
}

void tst_QQuickTreeModelAdaptor::expandAndTest(const QModelIndex &idx, QQuickTreeModelAdaptor1 &tma, bool expandable,
                                                  int expectedRowCountDifference)
{
    QSignalSpy rowsAboutToBeInsertedSpy(&tma, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
    QSignalSpy rowsInsertedSpy(&tma, SIGNAL(rowsInserted(QModelIndex,int,int)));
    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));

    int oldRowCount = tma.rowCount();
    tma.expand(idx);
    QCOMPARE(tma.isExpanded(idx), expandable);

    const QModelIndex &tmaIdx = tma.index(tma.itemIndex(idx));
    QCOMPARE(tma.data(tmaIdx, QQuickTreeModelAdaptor1::ExpandedRole).toBool(), expandable);

    if (expandable && expectedRowCountDifference != 0) {
        // Rows were added below the parent
        QCOMPARE(tma.rowCount(), oldRowCount + expectedRowCountDifference);
        QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsInsertedSpy.count());
        QVERIFY(rowsInsertedSpy.count() > 0);
        if (rowsInsertedSpy.count() == 1) {
            const QVariantList &rowsAboutToBeInsertedArgs = rowsAboutToBeInsertedSpy.takeFirst();
            const QVariantList &rowsInsertedArgs = rowsInsertedSpy.takeFirst();
            for (int i = 0; i < rowsInsertedArgs.count(); i++)
                QCOMPARE(rowsAboutToBeInsertedArgs.at(i), rowsInsertedArgs.at(i));
            QCOMPARE(rowsInsertedArgs.at(0).toModelIndex(), QModelIndex());
            QCOMPARE(rowsInsertedArgs.at(1).toInt(), tma.itemIndex(idx) + 1);
            QCOMPARE(rowsInsertedArgs.at(2).toInt(), tma.itemIndex(idx) + expectedRowCountDifference);
        }

        // Data changed for the parent's ExpandedRole (value checked above)
        QCOMPARE(dataChangedSpy.count(), 1);
        const QVariantList &dataChangedArgs = dataChangedSpy.first();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), QVector<int>(1, QQuickTreeModelAdaptor1::ExpandedRole));
    } else {
        QCOMPARE(tma.rowCount(), oldRowCount);
        QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
        QCOMPARE(rowsInsertedSpy.count(), 0);
    }
}

void tst_QQuickTreeModelAdaptor::collapseAndTest(const QModelIndex &idx, QQuickTreeModelAdaptor1 &tma,
                                                 bool expandable, int expectedRowCountDifference)
{
    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(QModelIndex,int,int)));
    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));

    int oldRowCount = tma.rowCount();
    tma.collapse(idx);
    QVERIFY(!tma.isExpanded(idx));

    const QModelIndex &tmaIdx = tma.index(tma.itemIndex(idx));
    if (tmaIdx.isValid())
        QCOMPARE(tma.data(tmaIdx, QQuickTreeModelAdaptor1::ExpandedRole).toBool(), false);

    if (expandable && expectedRowCountDifference != 0) {
        // Rows were removed below the parent
        QCOMPARE(tma.rowCount(), oldRowCount - expectedRowCountDifference);
        QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
        QCOMPARE(rowsRemovedSpy.count(), 1);
        const QVariantList &rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.takeFirst();
        const QVariantList &rowsRemovedArgs = rowsRemovedSpy.takeFirst();
        for (int i = 0; i < rowsRemovedArgs.count(); i++)
            QCOMPARE(rowsAboutToBeRemovedArgs.at(i), rowsRemovedArgs.at(i));
        QCOMPARE(rowsRemovedArgs.at(0).toModelIndex(), QModelIndex());
        QCOMPARE(rowsRemovedArgs.at(1).toInt(), tma.itemIndex(idx) + 1);
        QCOMPARE(rowsRemovedArgs.at(2).toInt(), tma.itemIndex(idx) + expectedRowCountDifference);

        // Data changed for the parent's ExpandedRole (value checked above)
        QVERIFY(dataChangedSpy.count() >= 1);
        const QVariantList &dataChangedArgs = dataChangedSpy.first();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), QVector<int>(1, QQuickTreeModelAdaptor1::ExpandedRole));
    } else {
        QCOMPARE(tma.rowCount(), oldRowCount);
        QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
        QCOMPARE(rowsRemovedSpy.count(), 0);
    }
}

bool tst_QQuickTreeModelAdaptor::rowRoleWasChanged(const QSignalSpy &captured, int row, int role)
{
    for (const QVariantList &args : captured) {
        const int startRow = args.at(0).toModelIndex().row();
        const int endRow = args.at(1).toModelIndex().row();
        if (row >= startRow && row <= endRow) {
            const QVector<int> roles = args.at(2).value<QVector<int>>();
            if (roles.contains(role))
                return true;
        }
    }
    return false;
}

void tst_QQuickTreeModelAdaptor::compareModels(QQuickTreeModelAdaptor1 &tma, TestModel &model)
{
    QModelIndex parent = tma.rootIndex();
    QStack<QModelIndex> parents;
    QModelIndex idx = model.index(0, 0, parent);
    int modelVisibleRows = model.rowCount(parent);
    for (int i = 0; i < tma.rowCount(); i++) {
        bool expanded = tma.isExpanded(i);
        compareData(i, tma, idx, model, expanded);
        if (expanded) {
            parents.push(parent);
            parent = idx;
            modelVisibleRows += model.rowCount(parent);
            idx = model.index(0, 0, parent);
        } else {
            while (idx.row() == model.rowCount(parent) - 1) {
                if (parents.isEmpty())
                    break;
                idx = parent;
                parent = parents.pop();
            }
            idx = model.index(idx.row() + 1, 0, parent);
        }
    }
    QCOMPARE(tma.rowCount(), modelVisibleRows);

    // Duplicates the model inspection above, but provides extra tests
    QVERIFY(tma.testConsistency());
}

void tst_QQuickTreeModelAdaptor::setModel()
{
    TestModel model(5, 1);
    QQuickTreeModelAdaptor1 tma;

    QSignalSpy modelChangedSpy(&tma, SIGNAL(modelChanged(QAbstractItemModel*)));
    tma.setModel(&model);
    QCOMPARE(modelChangedSpy.count(), 1);
    QCOMPARE(tma.model(), &model);

    // Set same model twice
    tma.setModel(&model);
    QCOMPARE(modelChangedSpy.count(), 1);

    modelChangedSpy.clear();
    tma.setModel(0);
    QCOMPARE(modelChangedSpy.count(), 1);
    QCOMPARE(tma.model(), static_cast<QAbstractItemModel *>(0));
}

void tst_QQuickTreeModelAdaptor::modelDestroyed()
{
    TestModel *model = new TestModel(5, 1);
    QQuickTreeModelAdaptor1 tma;

    QSignalSpy modelChangedSpy(&tma, SIGNAL(modelChanged(QAbstractItemModel*)));
    tma.setModel(model);
    QCOMPARE(modelChangedSpy.count(), 1);
    QCOMPARE(tma.model(), model);

    QModelIndex idx = model->index(0, 0);
    modelChangedSpy.clear();
    delete model;
    QCOMPARE(modelChangedSpy.count(), 1);
    QCOMPARE(tma.model(), (QAbstractItemModel *)0);
    tma.expand(idx); // No crash, all fine
}

void tst_QQuickTreeModelAdaptor::modelReset()
{
    TestModel model(5, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QSignalSpy modelAboutToBeResetSpy(&tma, SIGNAL(modelAboutToBeReset()));
    QSignalSpy modelResetSpy(&tma, SIGNAL(modelReset()));

    // Nothing expanded
    model.resetModel();
    QCOMPARE(modelAboutToBeResetSpy.count(), 1);
    QCOMPARE(modelResetSpy.count(), 1);
    QCOMPARE(tma.rowCount(), model.rowCount());
    compareModels(tma, model);

    // Expanded items should not be anymore
    tma.expand(model.index(0, 0));
    tma.expand(model.index(2, 0));
    tma.expand(model.index(2, 0, model.index(2, 0)));
    modelAboutToBeResetSpy.clear();
    modelResetSpy.clear();
    model.resetModel();
    QCOMPARE(modelAboutToBeResetSpy.count(), 1);
    QCOMPARE(modelResetSpy.count(), 1);
    QCOMPARE(tma.rowCount(), model.rowCount());
    compareModels(tma, model);
}

void tst_QQuickTreeModelAdaptor::rootIndex()
{
    TestModel model(5, 1);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QVERIFY(!tma.rootIndex().isValid());
    compareModels(tma, model);

    QSignalSpy rootIndexSpy(&tma, SIGNAL(rootIndexChanged()));
    QModelIndex rootIndex = model.index(0, 0);
    tma.setRootIndex(rootIndex);
    QCOMPARE(tma.rootIndex(), rootIndex);
    QCOMPARE(rootIndexSpy.count(), 1);
    compareModels(tma, model);

    rootIndexSpy.clear();
    rootIndex = model.index(2, 2, tma.rootIndex());
    tma.setRootIndex(rootIndex);
    QCOMPARE(tma.rootIndex(), rootIndex);
    QCOMPARE(rootIndexSpy.count(), 1);
    compareModels(tma, model);

    // Expand 1st visible item, business as usual
    expandAndTest(model.index(0, 0, rootIndex), tma, true /*expandable*/, 5);
    // Expand non root item descendant item, nothing should happen
    expandAndTest(model.index(0, 0), tma, true /*expandable*/, 0);
    // Collapse 1st visible item, business as usual
    collapseAndTest(model.index(0, 0, rootIndex), tma, true /*expandable*/, 5);
    // Collapse non root item descendant item, nothing should happen
    collapseAndTest(model.index(0, 0), tma, true /*expandable*/, 0);
}

void tst_QQuickTreeModelAdaptor::dataAccess()
{
    TestModel model(5, 1);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QCOMPARE(tma.rowCount(), model.rowCount());
    compareModels(tma, model);

    QModelIndex parentIdx = model.index(2, 0);
    QVERIFY(model.hasChildren(parentIdx));
    tma.expand(parentIdx);
    QVERIFY(tma.isExpanded(parentIdx));
    QCOMPARE(tma.rowCount(), model.rowCount() + model.rowCount(parentIdx));
    compareModels(tma, model);

    tma.collapse(parentIdx);
    QCOMPARE(tma.rowCount(), model.rowCount());
    compareModels(tma, model);
}

void tst_QQuickTreeModelAdaptor::dataChange()
{
    TestModel model(5, 1);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    const QModelIndex &idx = model.index(2, 0);
    model.setData(idx, QVariant(), Qt::DisplayRole);
    QCOMPARE(dataChangedSpy.count(), 1);
    const QVariantList &dataChangedArgs = dataChangedSpy.first();
    const QModelIndex &tmaIdx = tma.index(tma.itemIndex(idx));
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaIdx);
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaIdx);
    QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), QVector<int>(1, Qt::DisplayRole));
    compareModels(tma, model);

    {
        // Non expanded children shouldn't emit any signal
        dataChangedSpy.clear();
        const QModelIndex &childIdx = model.index(4, 0, idx);
        model.setData(childIdx, QVariant(), Qt::DisplayRole);
        QCOMPARE(dataChangedSpy.count(), 0);
        compareModels(tma, model);

        // But expanded children should
        tma.expand(idx);
        QVERIFY(tma.isExpanded(idx));
        dataChangedSpy.clear(); // expand() emits dataChanged() with ExpandedRole
        model.setData(childIdx, QVariant(), Qt::DisplayRole);
        QCOMPARE(dataChangedSpy.count(), 1);
        const QVariantList &dataChangedArgs = dataChangedSpy.first();
        const QModelIndex &tmaIdx = tma.index(tma.itemIndex(childIdx));
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), QVector<int>(1, Qt::DisplayRole));
        compareModels(tma, model);
    }
}

void tst_QQuickTreeModelAdaptor::groupedDataChange()
{
    TestModel model(10, 1);
    const QModelIndex &topLeftIdx = model.index(1, 0);
    const QModelIndex &bottomRightIdx = model.index(7, 0);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    const QVector<int> roles(1, Qt::DisplayRole);

    {
        // No expanded items
        model.groupedSetData(topLeftIdx, bottomRightIdx, roles);
        QCOMPARE(dataChangedSpy.count(), 1);
        compareModels(tma, model);

        const QModelIndex &tmaTLIdx = tma.index(tma.itemIndex(topLeftIdx));
        const QModelIndex &tmaBRIdx = tma.index(tma.itemIndex(bottomRightIdx));
        const QVariantList &dataChangedArgs = dataChangedSpy.first();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaTLIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaBRIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);
    }

    // One item expanded in the group range
    const QModelIndex &expandedIdx = model.index(4, 0);
    tma.expand(expandedIdx);
    QVERIFY(tma.isExpanded(expandedIdx));

    for (int i = 0; i < 2; i++) {
        const QModelIndex &tmaTLIdx = tma.index(tma.itemIndex(topLeftIdx));
        const QModelIndex &tmaExpandedIdx = tma.index(tma.itemIndex(expandedIdx));
        const QModelIndex &tmaExpandedSiblingIdx = tma.index(tma.itemIndex(expandedIdx.sibling(expandedIdx.row() + 1, 0)));
        const QModelIndex &tmaBRIdx = tma.index(tma.itemIndex(bottomRightIdx));

        dataChangedSpy.clear(); // expand() sends a dataChaned() signal
        model.groupedSetData(topLeftIdx, bottomRightIdx, roles);
        QCOMPARE(dataChangedSpy.count(), 2);
        compareModels(tma, model);

        QVariantList dataChangedArgs = dataChangedSpy.takeFirst();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaTLIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaExpandedIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);

        dataChangedArgs = dataChangedSpy.takeFirst();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaExpandedSiblingIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaBRIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);

        // Further expanded descendants should not change grouping
        tma.expand(model.index(0, 0, expandedIdx));
        QVERIFY(tma.isExpanded(expandedIdx));
    }
    tma.collapse(model.index(0, 0, expandedIdx));

    // Let's expand one more and see what happens...
    const QModelIndex &otherExpandedIdx = model.index(6, 0);
    tma.expand(otherExpandedIdx);
    QVERIFY(tma.isExpanded(otherExpandedIdx));

    for (int i = 0; i < 3; i++) {
        const QModelIndex &tmaTLIdx = tma.index(tma.itemIndex(topLeftIdx));
        const QModelIndex &tmaExpandedIdx = tma.index(tma.itemIndex(expandedIdx));
        const QModelIndex &tmaExpandedSiblingIdx = tma.index(tma.itemIndex(expandedIdx.sibling(expandedIdx.row() + 1, 0)));
        const QModelIndex &tmaOtherExpandedIdx = tma.index(tma.itemIndex(otherExpandedIdx));
        const QModelIndex &tmaOtherExpandedSiblingIdx = tma.index(tma.itemIndex(otherExpandedIdx.sibling(otherExpandedIdx.row() + 1, 0)));
        const QModelIndex &tmaBRIdx = tma.index(tma.itemIndex(bottomRightIdx));

        dataChangedSpy.clear(); // expand() sends a dataChaned() signal
        model.groupedSetData(topLeftIdx, bottomRightIdx, roles);
        QCOMPARE(dataChangedSpy.count(), 3);
        compareModels(tma, model);

        QVariantList dataChangedArgs = dataChangedSpy.takeFirst();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaTLIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaExpandedIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);

        dataChangedArgs = dataChangedSpy.takeFirst();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaExpandedSiblingIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaOtherExpandedIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);

        dataChangedArgs = dataChangedSpy.takeFirst();
        QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tmaOtherExpandedSiblingIdx);
        QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tmaBRIdx);
        QCOMPARE(dataChangedArgs.at(2).value<QVector<int> >(), roles);

        // Further expanded descendants should not change grouping
        if (i == 0) {
            tma.expand(model.index(0, 0, expandedIdx));
            QVERIFY(tma.isExpanded(expandedIdx));
        } else {
            tma.expand(model.index(0, 0, otherExpandedIdx));
            QVERIFY(tma.isExpanded(expandedIdx));
        }
    }
}

void tst_QQuickTreeModelAdaptor::expandAndCollapse_data()
{
    QTest::addColumn<int>("parentRow");
    QTest::newRow("First") << 0;
    QTest::newRow("Middle") << 2;
    QTest::newRow("Last") << 4;
    QTest::newRow("Non expandable") << 3;
}

void tst_QQuickTreeModelAdaptor::expandAndCollapse()
{
    QFETCH(int, parentRow);
    TestModel model(5, 1);
    const QModelIndex &parentIdx = model.index(parentRow, 0);
    bool expandable = model.hasChildren(parentIdx);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    expandAndTest(parentIdx, tma, expandable, model.rowCount(parentIdx));
    compareModels(tma, model);

    collapseAndTest(parentIdx, tma, expandable, model.rowCount(parentIdx));
    compareModels(tma, model);
}

void tst_QQuickTreeModelAdaptor::expandAndCollapse2ndLevel()
{
    const int expandRows[] = { 0, 2, 4, 3 };
    const int expandRowsCount = sizeof(expandRows) / sizeof(expandRows[0]);
    for (int i = 0; i < expandRowsCount - 1; i++) { // Skip last non-expandable row
        TestModel model(5, 1);
        const QModelIndex &parentIdx = model.index(expandRows[i], 0);
        QVERIFY(model.hasChildren(parentIdx));

        QQuickTreeModelAdaptor1 tma;
        tma.setModel(&model);

        tma.expand(parentIdx);
        QVERIFY(tma.isExpanded(parentIdx));
        QCOMPARE(tma.rowCount(), model.rowCount() + model.rowCount(parentIdx));

        for (int j = 0; j < expandRowsCount; j++) {
            const QModelIndex &childIdx = model.index(expandRows[j], 0, parentIdx);
            bool expandable = model.hasChildren(childIdx);

            // Expand child
            expandAndTest(childIdx, tma, expandable, model.rowCount(childIdx));
            compareModels(tma, model);
            // Collapse child
            collapseAndTest(childIdx, tma, expandable, model.rowCount(childIdx));
            compareModels(tma, model);

            // Expand child again
            expandAndTest(childIdx, tma, expandable, model.rowCount(childIdx));
            compareModels(tma, model);
            // Collapse parent -> child node invisible, but expanded
            collapseAndTest(parentIdx, tma, true, model.rowCount(parentIdx) + model.rowCount(childIdx));
            compareModels(tma, model);
            QCOMPARE(tma.isExpanded(childIdx), expandable);
            // Expand parent again
            expandAndTest(parentIdx, tma, true, model.rowCount(parentIdx) + model.rowCount(childIdx));
            compareModels(tma, model);

            // Collapse parent -> child node invisible, but expanded
            collapseAndTest(parentIdx, tma, true, model.rowCount(parentIdx) + model.rowCount(childIdx));
            compareModels(tma, model);
            QCOMPARE(tma.isExpanded(childIdx), expandable);
            // Collapse child -> nothing should change
            collapseAndTest(childIdx, tma, false, 0);
            compareModels(tma, model);
            // Expand parent again
            expandAndTest(parentIdx, tma, true, model.rowCount(parentIdx));
            compareModels(tma, model);

            // Expand child, one last time
            expandAndTest(childIdx, tma, expandable, model.rowCount(childIdx));
            compareModels(tma, model);
            // Collapse child, and done
            collapseAndTest(childIdx, tma, expandable, model.rowCount(childIdx));
            compareModels(tma, model);
        }
    }
}

void tst_QQuickTreeModelAdaptor::layoutChange()
{
    TestModel model(5, 1);
    const QModelIndex &idx = model.index(0, 0);
    const QModelIndex &idx2 = model.index(2, 0);

    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    // Nothing expanded
    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    model.changeLayout();
    QCOMPARE(dataChangedSpy.count(), 1);
    QVariantList dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(0));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.rowCount() - 1));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    compareModels(tma, model);

    // One item expanded
    tma.expand(idx);
    QVERIFY(tma.isExpanded(idx));
    dataChangedSpy.clear();
    model.changeLayout();
    QCOMPARE(dataChangedSpy.count(), 1);
    dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(0));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.rowCount() - 1));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    compareModels(tma, model);

    // One parent layout change, expanded
    dataChangedSpy.clear();
    QList<QPersistentModelIndex> parents;
    parents << idx;
    model.changeLayout(parents);
    QCOMPARE(dataChangedSpy.count(), 1);
    dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(tma.itemIndex(model.index(0, 0, idx))));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.itemIndex(model.index(model.rowCount(idx) - 1, 0, idx))));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    compareModels(tma, model);

    // One parent layout change, collapsed
    tma.collapse(idx);
    dataChangedSpy.clear();
    model.changeLayout(parents);
    QCOMPARE(dataChangedSpy.count(), 0);
    compareModels(tma, model);

    // Two-parent layout change, both collapsed
    parents << idx2;
    dataChangedSpy.clear();
    model.changeLayout(parents);
    QCOMPARE(dataChangedSpy.count(), 0);
    compareModels(tma, model);

    // Two-parent layout change, only one expanded
    tma.expand(idx2);
    QVERIFY(tma.isExpanded(idx2));
    dataChangedSpy.clear();
    model.changeLayout(parents);
    QCOMPARE(dataChangedSpy.count(), 1);
    dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(tma.itemIndex(model.index(0, 0, idx2))));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.itemIndex(model.index(model.rowCount(idx2) - 1, 0, idx2))));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    compareModels(tma, model);

    // Two-parent layout change, both expanded
    tma.expand(idx);
    QVERIFY(tma.isExpanded(idx));
    dataChangedSpy.clear();
    model.changeLayout(parents);
    QCOMPARE(dataChangedSpy.count(), 2);
    dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(tma.itemIndex(model.index(0, 0, idx))));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.itemIndex(model.index(model.rowCount(idx) - 1, 0, idx))));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    dataChangedArgs = dataChangedSpy.takeFirst();
    QCOMPARE(dataChangedArgs.at(0).toModelIndex(), tma.index(tma.itemIndex(model.index(0, 0, idx2))));
    QCOMPARE(dataChangedArgs.at(1).toModelIndex(), tma.index(tma.itemIndex(model.index(model.rowCount(idx2) - 1, 0, idx2))));
    QVERIFY(dataChangedArgs.at(2).value<QVector<int> >().isEmpty());
    compareModels(tma, model);
}

static const int ModelRowCount = 9;

void tst_QQuickTreeModelAdaptor::removeRows_data()
{
    QTest::addColumn<int>("removeFromRow");
    QTest::addColumn<int>("removeCount");
    QTest::addColumn<int>("removeParentRow");
    QTest::addColumn<int>("expandRow");
    QTest::addColumn<int>("expandParentRow");
    QTest::addColumn<int>("expectedRemovedCount");

    QTest::newRow("Nothing expanded, remove 1st row") << 0 << 1 << -1 << -1 << -1 << 1;
    QTest::newRow("Expand 1st row, remove 1st row") << 0 << 1 << -1 << 0 << -1 << 1 + ModelRowCount;
    QTest::newRow("Expand last row, remove 1st row") << 0 << 1 << -1 << ModelRowCount - 1 << -1 << 1;
    QTest::newRow("Nothing expanded, remove last row") << ModelRowCount - 1 << 1 << -1 << -1 << -1 << 1;
    QTest::newRow("Expand 1st row, remove last row") << ModelRowCount - 1 << 1 << -1 << 0 << -1 << 1;
    QTest::newRow("Expand last row, remove last row") << ModelRowCount - 1 << 1 << -1 << ModelRowCount - 1 << -1 << 1 + ModelRowCount;
    QTest::newRow("Remove child row, parent collapsed") << 2 << 1 << 0 << -1 << -1 << 0;
    QTest::newRow("Remove child row, parent expanded") << 2 << 1 << 0 << 0 << -1 << 1;
    QTest::newRow("Remove several rows, nothing expanded") << 2 << 5 << -1 << -1 << -1 << 5;
    QTest::newRow("Remove several rows, 1st row expanded") << 2 << 5 << -1 << 0 << -1 << 5;
    QTest::newRow("Remove several rows, last row expanded") << 2 << 5 << -1 << ModelRowCount - 1 << -1 << 5;
    QTest::newRow("Remove several rows, one of them expanded") << 2 << 5 << -1 << 4 << -1 << 5 + ModelRowCount;
    QTest::newRow("Remove all rows, nothing expanded") << 0 << ModelRowCount << -1 << -1 << -1 << ModelRowCount;
    QTest::newRow("Remove all rows, 1st row expanded") << 0 << ModelRowCount << -1 << 0 << -1 << ModelRowCount * 2;
    QTest::newRow("Remove all rows, last row expanded") << 0 << ModelRowCount << -1 << ModelRowCount - 1 << -1 << ModelRowCount * 2;
    QTest::newRow("Remove all rows, random one expanded") << 0 << ModelRowCount << -1 << 4 << -1 << ModelRowCount * 2;
}

void tst_QQuickTreeModelAdaptor::removeRows()
{
    QFETCH(int, removeFromRow);
    QFETCH(int, removeCount);
    QFETCH(int, removeParentRow);
    QFETCH(int, expandRow);
    QFETCH(int, expandParentRow);
    QFETCH(int, expectedRemovedCount);

    TestModel model(ModelRowCount, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    const QModelIndex &expandParentIdx = expandParentRow == -1 ? QModelIndex() : model.index(expandParentRow, 0);
    if (expandParentIdx.isValid()) {
        tma.expand(expandParentIdx);
        QVERIFY(tma.isExpanded(expandParentIdx));
    }
    const QModelIndex &expandIdx = model.index(expandRow, 0, expandParentIdx);
    if (expandIdx.isValid()) {
        tma.expand(expandIdx);
        QVERIFY(tma.isExpanded(expandIdx));
    }

    const QModelIndex &removeParentIdx = removeParentRow == -1 ? QModelIndex() : model.index(removeParentRow, 0);
    const QModelIndex &removeIdx = model.index(removeFromRow, 0, removeParentIdx);
    int tmaItemIdx = tma.itemIndex(removeIdx);

    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(const QModelIndex&, int, int)));
    model.removeRows(removeFromRow, removeCount, removeParentIdx);
    if (expectedRemovedCount == 0) {
        QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
        QCOMPARE(rowsRemovedSpy.count(), 0);
    } else {
        QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
        QCOMPARE(rowsRemovedSpy.count(), 1);
        QVariantList rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
        QVariantList rowsRemovedArgs = rowsRemovedSpy.first();
        QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
        QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
        QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), tmaItemIdx);
        QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), tmaItemIdx + expectedRemovedCount - 1);
    }
}

void tst_QQuickTreeModelAdaptor::removeRowsChildrenAndParent()
{
    TestModel model(ModelRowCount, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    // Expand the first node
    const QModelIndex &parent = model.index(0, 0);
    tma.expand(parent);
    QVERIFY(tma.isExpanded(parent));

    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(const QModelIndex&, int, int)));

    // Remove the first node children
    int expectedRemovedCount = model.rowCount(parent);
    int tmaItemIdx = tma.itemIndex(model.index(0, 0, parent));
    QCOMPARE(tmaItemIdx, tma.itemIndex(parent) + 1);
    model.removeRows(0, expectedRemovedCount, parent);
    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
    QCOMPARE(rowsRemovedSpy.count(), 1);
    QVariantList rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
    QVariantList rowsRemovedArgs = rowsRemovedSpy.first();
    QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), tmaItemIdx);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), tmaItemIdx + expectedRemovedCount - 1);

    // Remove the first node
    rowsAboutToBeRemovedSpy.clear();
    rowsRemovedSpy.clear();
    model.removeRows(0, 1, QModelIndex());
    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
    QCOMPARE(rowsRemovedSpy.count(), 1);
    rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
    rowsRemovedArgs = rowsRemovedSpy.first();
    QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), 0);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), 0);
}

void tst_QQuickTreeModelAdaptor::removeChildrenMoveParent()
{
    TestModel model(ModelRowCount, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    // Expand the first node
    const QModelIndex &parent = model.index(0, 0);
    tma.expand(parent);
    QVERIFY(tma.isExpanded(parent));

    // Remove the first node children
    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(const QModelIndex&, int, int)));
    int expectedRemovedCount = model.rowCount(parent);
    int tmaItemIdx = tma.itemIndex(model.index(0, 0, parent));
    QCOMPARE(tmaItemIdx, tma.itemIndex(parent) + 1);
    model.removeRows(0, expectedRemovedCount, parent);
    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
    QCOMPARE(rowsRemovedSpy.count(), 1);
    QVariantList rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
    QVariantList rowsRemovedArgs = rowsRemovedSpy.first();
    QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), tmaItemIdx);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), tmaItemIdx + expectedRemovedCount - 1);

    // Move the first node
    QSignalSpy rowsAboutToBeMovedSpy(&tma, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
    QSignalSpy rowsMovedSpy(&tma, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
    model.moveRows(QModelIndex(), 0, 1, QModelIndex(), 3);
    QCOMPARE(rowsAboutToBeMovedSpy.count(), 1);
    QCOMPARE(rowsRemovedSpy.count(), 1);
    QVariantList rowsAboutToBeMovedArgs = rowsAboutToBeMovedSpy.first();
    QVariantList rowsMovedArgs = rowsMovedSpy.first();
    QCOMPARE(rowsAboutToBeMovedArgs, rowsMovedArgs);
    QCOMPARE(rowsAboutToBeMovedArgs.at(0).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeMovedArgs.at(1).toInt(), 0);
    QCOMPARE(rowsAboutToBeMovedArgs.at(2).toInt(), 0);
    QCOMPARE(rowsAboutToBeMovedArgs.at(3).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeMovedArgs.at(4).toInt(), 3);
}

void tst_QQuickTreeModelAdaptor::removeChildrenRelayoutParent()
{
    TestModel model(ModelRowCount, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    // Expand the first node
    const QModelIndex &parent = model.index(0, 0);
    tma.expand(parent);
    QVERIFY(tma.isExpanded(parent));

    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(const QModelIndex&, int, int)));

    // Remove the first node children
    int expectedRemovedCount = model.rowCount(parent);
    int tmaItemIdx = tma.itemIndex(model.index(0, 0, parent));
    QCOMPARE(tmaItemIdx, tma.itemIndex(parent) + 1);
    model.removeRows(0, expectedRemovedCount, parent);
    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
    QCOMPARE(rowsRemovedSpy.count(), 1);
    QVariantList rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
    QVariantList rowsRemovedArgs = rowsRemovedSpy.first();
    QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
    QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), tmaItemIdx);
    QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), tmaItemIdx + expectedRemovedCount - 1);

    // Relayout the first node
    QSignalSpy dataChanged(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    QList<QPersistentModelIndex> parents;
    parents << parent;
    model.changeLayout(parents);
    QCOMPARE(dataChanged.count(), 0);
}

void tst_QQuickTreeModelAdaptor::insertRows_data()
{
    QTest::addColumn<int>("insertFromRow");
    QTest::addColumn<int>("insertCount");
    QTest::addColumn<int>("insertParentRow");
    QTest::addColumn<int>("expandRow");
    QTest::addColumn<int>("expandParentRow");
    QTest::addColumn<int>("expectedInsertedCount");

    QTest::newRow("Nothing expanded, insert 1st row") << 0 << 1 << -1 << -1 << -1 << 1;
    QTest::newRow("Expand 1st row, insert 1st row") << 0 << 1 << -1 << 0 << -1 << 1;
    QTest::newRow("Expand last row, insert 1st row") << 0 << 1 << -1 << ModelRowCount - 1 << -1 << 1;
    QTest::newRow("Nothing expanded, insert before the last row") << ModelRowCount - 1 << 1 << -1 << -1 << -1 << 1;
    QTest::newRow("Nothing expanded, insert after the last row") << ModelRowCount << 1 << -1 << -1 << -1 << 1;
    QTest::newRow("Expand 1st row, insert before the last row") << ModelRowCount - 1 << 1 << -1 << 0 << -1 << 1;
    QTest::newRow("Expand 1st row, insert after the last row") << ModelRowCount << 1 << -1 << 0 << -1 << 1;
    QTest::newRow("Expand last row, insert before the last row") << ModelRowCount - 1 << 1 << -1 << ModelRowCount - 1 << -1 << 1;
    QTest::newRow("Expand last row, insert after the last row") << ModelRowCount << 1 << -1 << ModelRowCount - 1 << -1 << 1;
    QTest::newRow("Insert child row, parent collapsed") << 2 << 1 << 0 << -1 << -1 << 0;
    QTest::newRow("Insert child row, parent expanded") << 2 << 1 << 0 << 0 << -1 << 1;
    QTest::newRow("Insert several rows, nothing expanded") << 2 << 5 << -1 << -1 << -1 << 5;
    QTest::newRow("Insert several rows, 1st row expanded") << 2 << 5 << -1 << 0 << -1 << 5;
    QTest::newRow("Insert several rows, last row expanded") << 2 << 5 << -1 << ModelRowCount - 1 << -1 << 5;
}

void tst_QQuickTreeModelAdaptor::insertRows()
{
    QFETCH(int, insertFromRow);
    QFETCH(int, insertCount);
    QFETCH(int, insertParentRow);
    QFETCH(int, expandRow);
    QFETCH(int, expandParentRow);
    QFETCH(int, expectedInsertedCount);

    TestModel model(ModelRowCount, 1);
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    const QModelIndex &expandParentIdx = expandParentRow == -1 ? QModelIndex() : model.index(expandParentRow, 0);
    if (expandParentIdx.isValid()) {
        tma.expand(expandParentIdx);
        QVERIFY(tma.isExpanded(expandParentIdx));
    }
    const QModelIndex &expandIdx = model.index(expandRow, 0, expandParentIdx);
    if (expandIdx.isValid()) {
        tma.expand(expandIdx);
        QVERIFY(tma.isExpanded(expandIdx));
    }

    const QModelIndex &insertParentIdx = insertParentRow == -1 ? QModelIndex() : model.index(insertParentRow, 0);
    const QModelIndex &insertIdx = model.index(insertFromRow, 0, insertParentIdx);
    int tmaItemIdx = insertFromRow == model.rowCount(insertParentIdx) ? tma.rowCount() : tma.itemIndex(insertIdx);

    QSignalSpy rowsAboutToBeInsertedSpy(&tma, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)));
    QSignalSpy rowsInsertedSpy(&tma, SIGNAL(rowsInserted(const QModelIndex&, int, int)));
    model.insertRows(insertFromRow, insertCount, insertParentIdx);
    if (expectedInsertedCount == 0) {
        QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
        QCOMPARE(rowsInsertedSpy.count(), 0);
    } else {
        QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1);
        QCOMPARE(rowsInsertedSpy.count(), 1);
        QVariantList rowsAboutToBeInsertedArgs = rowsAboutToBeInsertedSpy.first();
        QVariantList rowsInsertedArgs = rowsInsertedSpy.first();
        QCOMPARE(rowsAboutToBeInsertedArgs, rowsInsertedArgs);
        QCOMPARE(rowsAboutToBeInsertedArgs.at(0).toModelIndex(), QModelIndex());
        QCOMPARE(rowsAboutToBeInsertedArgs.at(1).toInt(), tmaItemIdx);
        QCOMPARE(rowsAboutToBeInsertedArgs.at(2).toInt(), tmaItemIdx + expectedInsertedCount - 1);
        QCOMPARE(tma.itemIndex(model.index(insertFromRow, 0, insertParentIdx)), tmaItemIdx);
    }
}

enum MoveSignalType {
    RowsMoved = 0, RowsInserted, RowsRemoved
};

void tst_QQuickTreeModelAdaptor::moveRows_data()
{
    QTest::addColumn<int>("sourceRow");
    QTest::addColumn<bool>("expandSource");
    QTest::addColumn<int>("moveCount");
    QTest::addColumn<int>("sourceParentRow");
    QTest::addColumn<bool>("expandSourceParent");
    QTest::addColumn<int>("destRow");
    QTest::addColumn<bool>("expandDest");
    QTest::addColumn<int>("destParentRow");
    QTest::addColumn<bool>("expandDestParent");
    QTest::addColumn<int>("expandRow");
    QTest::addColumn<int>("expandParentRow");
    QTest::addColumn<int>("signalType");
    QTest::addColumn<int>("expectedMovedCount");

    QTest::newRow("From and to top-level parent")
            << 0 << false << 1 << -1 << false
            << 3 << false << -1 << false
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to top-level parent, expanded")
            << 0 << true << 1 << -1 << false
            << 3 << false << -1 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 1;
    QTest::newRow("From and to top-level parent, backwards")
            << 4 << false << 1 << -1 << false
            << 0 << false << -1 << false
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to top-level parent, expanded, backwards")
            << 4 << true << 1 << -1 << false
            << 0 << false << -1 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 1;
    QTest::newRow("Moving between collapsed parents")
            << 0 << false << 1 << 0 << false
            << 0 << false << 2 << false
            << -1 << -1 << (int)RowsMoved << 0;
    QTest::newRow("From expanded parent to collapsed parent")
            << 0 << false << 1 << 0 << true
            << 0 << false << 2 << false
            << -1 << -1 << (int)RowsRemoved << 1;
    QTest::newRow("From collapsed parent to expanded parent")
            << 0 << false << 1 << 0 << false
            << 0 << false << 2 << true
            << -1 << -1 << (int)RowsInserted << 1;
    QTest::newRow("From and to same expanded parent")
            << 0 << false << 1 << 0 << true
            << 2 << false << 0 << false
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From expanded parent to collapsed parent, expanded row")
            << 0 << true << 1 << 0 << true
            << 0 << false << 2 << false
            << -1 << -1 << (int)RowsRemoved << ModelRowCount + 1;
    QTest::newRow("From collapsed parent to expanded parent, expanded row")
            << 0 << true << 1 << 0 << false
            << 0 << false << 2 << true
            << -1 << -1 << (int)RowsInserted << ModelRowCount + 1;
    QTest::newRow("From and to same expanded parent, expanded row, forward")
            << 0 << true << 1 << 0 << true
            << 5 << false << 0 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 1;
    QTest::newRow("From and to same expanded parent, expanded row, last row")
            << 0 << true << 1 << 0 << true
            << ModelRowCount << false << 0 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 1;
    QTest::newRow("From and to same expanded parent, expanded row, several")
            << 0 << true << 3 << 0 << true
            << 5 << false << 0 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 3;
    QTest::newRow("From and to same expanded parent, expanded row, backward")
            << 6 << true << 1 << 0 << true
            << 0 << false << 0 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 1;
    QTest::newRow("From and to same expanded parent, expanded row, several, backward")
            << 6 << true << 2 << 0 << true
            << 0 << false << 0 << false
            << -1 << -1 << (int)RowsMoved << ModelRowCount + 2;
    QTest::newRow("From and to different expanded parents")
            << 0 << false << 1 << 0 << true
            << 1 << false << 4 << true
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to different expanded parents, backward")
            << 0 << false << 1 << 4 << true
            << 2 << false << 0 << true
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to different expanded parents, up in level")
            << 0 << false << 1 << 0 << true
            << 5 << true << -1 << true
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to different expanded parents, up in level, backwards")
            << 0 << false << 1 << 4 << true
            << 1 << false << -1 << true
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to different expanded parents, up in level, as 1st item")
            << 0 << false << 1 << 0 << true
            << 0 << false << -1 << true
            << -1 << -1 << (int)RowsMoved << 1;
    QTest::newRow("From and to different expanded parents, backward, up in level")
            << 0 << false << 1 << 4 << true
            << 2 << false << 0 << true
            << -1 << -1 << (int)RowsMoved << 1;
}

void tst_QQuickTreeModelAdaptor::moveRows()
{
    QFETCH(int, sourceRow);
    QFETCH(bool, expandSource);
    QFETCH(int, moveCount);
    QFETCH(int, sourceParentRow);
    QFETCH(bool, expandSourceParent);
    QFETCH(int, destRow);
    QFETCH(bool, expandDest);
    QFETCH(int, destParentRow);
    QFETCH(bool, expandDestParent);
    QFETCH(int, expandRow);
    QFETCH(int, expandParentRow);
    QFETCH(int, signalType);
    QFETCH(int, expectedMovedCount);

    TestModel model(ModelRowCount, 1);
    model.alternateChildlessRows = false;
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    const QModelIndex &expandParentIdx = expandParentRow == -1 ? QModelIndex() : model.index(expandParentRow, 0);
    if (expandParentIdx.isValid()) {
        tma.expand(expandParentIdx);
        QVERIFY(tma.isExpanded(expandParentIdx));
    }
    const QModelIndex &expandIdx = model.index(expandRow, 0, expandParentIdx);
    if (expandIdx.isValid()) {
        tma.expand(expandIdx);
        QVERIFY(tma.isExpanded(expandIdx));
    }

    const QModelIndex &sourceParentIdx = sourceParentRow == -1 ? QModelIndex() : model.index(sourceParentRow, 0);
    if (expandSourceParent && sourceParentIdx.isValid()) {
        tma.expand(sourceParentIdx);
        QVERIFY(tma.isExpanded(sourceParentIdx));
    }
    const QModelIndex &sourceIdx = model.index(sourceRow, 0, sourceParentIdx);
    if (expandSource) {
        tma.expand(sourceIdx);
        QVERIFY(tma.isExpanded(sourceIdx));
    }

    const QModelIndex &destParentIdx = destParentRow == -1 ? QModelIndex() : model.index(destParentRow, 0);
    if (expandDestParent && destParentIdx.isValid()) {
        tma.expand(destParentIdx);
        QVERIFY(tma.isExpanded(destParentIdx));
    }
    const QModelIndex &destIdx = model.index(destRow, 0, destParentIdx);
    if (expandDest) {
        tma.expand(destIdx);
        QVERIFY(tma.isExpanded(destIdx));
    }

    int tmaSourceItemIdx = signalType == RowsInserted ? -1 // Not tested if RowsInserted
                           : tma.itemIndex(sourceIdx);
    int tmaDestItemIdx = signalType == RowsRemoved ? -1 : // Not tested if RowsRemoved
                         destRow == model.rowCount(destParentIdx) ? -1  /* FIXME */ : tma.itemIndex(destIdx);

    QSignalSpy rowsAboutToBeMovedSpy(&tma, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
    QSignalSpy rowsMovedSpy(&tma, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
    QSignalSpy rowsAboutToBeInsertedSpy(&tma, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)));
    QSignalSpy rowsInsertedSpy(&tma, SIGNAL(rowsInserted(const QModelIndex&, int, int)));
    QSignalSpy rowsAboutToBeRemovedSpy(&tma, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
    QSignalSpy rowsRemovedSpy(&tma, SIGNAL(rowsRemoved(const QModelIndex&, int, int)));

    QVERIFY(model.moveRows(sourceParentIdx, sourceRow, moveCount, destParentIdx, destRow));

    if (signalType != RowsMoved || expectedMovedCount == 0) {
        QCOMPARE(rowsAboutToBeMovedSpy.count(), 0);
        QCOMPARE(rowsMovedSpy.count(), 0);
    }
    if (signalType != RowsInserted || expectedMovedCount == 0) {
        QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
        QCOMPARE(rowsInsertedSpy.count(), 0);
    }
    if (signalType != RowsRemoved || expectedMovedCount == 0) {
        QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
        QCOMPARE(rowsRemovedSpy.count(), 0);
    }

    if (expectedMovedCount != 0) {
        if (signalType == RowsMoved) {
            QCOMPARE(rowsAboutToBeMovedSpy.count(), 1);
            QCOMPARE(rowsMovedSpy.count(), 1);
            QVariantList rowsAboutToBeMovedArgs = rowsAboutToBeMovedSpy.first();
            QVariantList rowsMovedArgs = rowsMovedSpy.first();
            QCOMPARE(rowsAboutToBeMovedArgs, rowsMovedArgs);
            QCOMPARE(rowsAboutToBeMovedArgs.at(0).toModelIndex(), QModelIndex());
            QCOMPARE(rowsAboutToBeMovedArgs.at(1).toInt(), tmaSourceItemIdx);
            QCOMPARE(rowsAboutToBeMovedArgs.at(2).toInt(), tmaSourceItemIdx + expectedMovedCount - 1);
            QCOMPARE(rowsAboutToBeMovedArgs.at(3).toModelIndex(), QModelIndex());
            if (tmaDestItemIdx != -1)
                QCOMPARE(rowsAboutToBeMovedArgs.at(4).toInt(), tmaDestItemIdx);
        } else if (signalType == RowsInserted) {
            // We only test with one level of expanded children here, so we can do
            // exhaustive testing depending on whether the moved row is expanded.
            int signalCount = expandSource ? 2 : 1;
            QCOMPARE(rowsAboutToBeInsertedSpy.count(), signalCount);
            QCOMPARE(rowsInsertedSpy.count(), signalCount);
            QVariantList rowsAboutToBeInsertedArgs = rowsAboutToBeInsertedSpy.takeFirst();
            QVariantList rowsInsertedArgs = rowsInsertedSpy.takeFirst();
            QCOMPARE(rowsAboutToBeInsertedArgs, rowsInsertedArgs);
            QCOMPARE(rowsAboutToBeInsertedArgs.at(0).toModelIndex(), QModelIndex());
            QCOMPARE(rowsAboutToBeInsertedArgs.at(1).toInt(), tmaDestItemIdx);
            if (expandSource) {
                QCOMPARE(rowsAboutToBeInsertedArgs.at(2).toInt(), tmaDestItemIdx);
                rowsAboutToBeInsertedArgs = rowsAboutToBeInsertedSpy.first();
                rowsInsertedArgs = rowsInsertedSpy.first();
                QCOMPARE(rowsAboutToBeInsertedArgs, rowsInsertedArgs);
                QCOMPARE(rowsAboutToBeInsertedArgs.at(0).toModelIndex(), QModelIndex());
                QCOMPARE(rowsAboutToBeInsertedArgs.at(1).toInt(), tmaDestItemIdx + 1);
            }
            QCOMPARE(rowsAboutToBeInsertedArgs.at(2).toInt(), tmaDestItemIdx + expectedMovedCount - 1);
            QCOMPARE(tma.itemIndex(model.index(destRow, 0, destParentIdx)), tmaDestItemIdx);
        } else if (signalType == RowsRemoved) {
            QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
            QCOMPARE(rowsRemovedSpy.count(), 1);
            QVariantList rowsAboutToBeRemovedArgs = rowsAboutToBeRemovedSpy.first();
            QVariantList rowsRemovedArgs = rowsRemovedSpy.first();
            QCOMPARE(rowsAboutToBeRemovedArgs, rowsRemovedArgs);
            QCOMPARE(rowsAboutToBeRemovedArgs.at(0).toModelIndex(), QModelIndex());
            QCOMPARE(rowsAboutToBeRemovedArgs.at(1).toInt(), tmaSourceItemIdx);
            QCOMPARE(rowsAboutToBeRemovedArgs.at(2).toInt(), tmaSourceItemIdx + expectedMovedCount - 1);
        }
    }
    QVERIFY(tma.testConsistency());
    compareModels(tma, model);
}

void tst_QQuickTreeModelAdaptor::moveRowsDataChanged_data()
{
    /* This is the list of rows in the *list* model which are expanded. */
    QTest::addColumn<QVector<int>>("expandedRows");

    /* Here's the row to be moved (always just one) and the destination
     * position. We use a QVector<int> to identify a single row of the tree
     * model: the array value at index n represents the row number at the depth
     * n.
     */
    QTest::addColumn<QVector<int>>("sourcePath");
    QTest::addColumn<QVector<int>>("destPath");

    /* This is the list of expected changed rows in the *list* model. */
    QTest::addColumn<QSet<int>>("expectedRowChanges");

    QTest::newRow("From and to top-level parent")
            << QVector<int> {}
            << QVector<int> { 4 }
            << QVector<int> { 3 }
            << QSet<int> { 3, 4 };

    QTest::newRow("From and to top-level parent, expanded")
            << QVector<int> { 3, 5 }
            << QVector<int> { 4 }
            << QVector<int> { 3 }
            << QSet<int> { 3, 4, 5, 6, 7, 8, 9 };

    QTest::newRow("From and to top-level parent, expanded, down")
            << QVector<int> { 3, 5 }
            << QVector<int> { 3 }
            << QVector<int> { 5 }
            << QSet<int> { 3, 4, 5, 6, 7, 8, 9 };

    /* Expected visible result:
     * A      A
     * D      D
     * `-E    |-E
     * F      `-H
     * G   -> F
     * |-H    G
     * |-I    |-I
     * `-L    `-L
     * M      M
     */
    QTest::newRow("Visible move, different parents")
            << QVector<int> { 3, 1 }
            << QVector<int> { 3, 0 }
            << QVector<int> { 1, 1 }
            << QSet<int> { 3, 4, 5, 6, 7 };

    QTest::newRow("Move to non expanded parent")
            << QVector<int> {}
            << QVector<int> { 3 }
            << QVector<int> { 1, 0 }
            << QSet<int> { 3 };
}

void tst_QQuickTreeModelAdaptor::moveRowsDataChanged()
{
    QFETCH(QVector<int>, expandedRows);
    QFETCH(QVector<int>, sourcePath);
    QFETCH(QVector<int>, destPath);
    QFETCH(QSet<int>, expectedRowChanges);

    TestModel model(0, 1);
    model.alternateChildlessRows = false;
    model.fetchMore(QModelIndex());
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    /* Build this model:
     *   A
     *   |-B
     *   `-C
     *   D
     *   `-E
     *   F
     *   G
     *   |-H
     *   |-I
     *   | |-J
     *   | `-K
     *   `-L
     *   M
     */
    model.insertRows(0, 5, QModelIndex());
    QModelIndex index = model.index(0, 0);
    model.insertRows(0, 2, index);
    index = model.index(1, 0);
    model.insertRows(0, 1, index);
    index = model.index(3, 0);
    model.insertRows(0, 3, index);
    index = model.index(1, 0, index);
    model.insertRows(0, 2, index);

    for (int row : expandedRows) {
        tma.expandRow(row);
    }

    /* Find the source index */
    int sourceRow = sourcePath.takeLast();
    QModelIndex sourceIndex;
    for (int row : sourcePath) {
        sourceIndex = model.index(row, 0, sourceIndex);
    }

    /* Find the destination index */
    int destRow = destPath.takeLast();
    QModelIndex destIndex;
    for (int row : destPath) {
        destIndex = model.index(row, 0, destIndex);
    }

    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    QVERIFY(dataChangedSpy.isValid());

    QVERIFY(model.moveRows(sourceIndex, sourceRow, 1, destIndex, destRow));

    QSet<int> emittedChanges;
    for (int i = 0; i < dataChangedSpy.count(); i++) {
        QVariantList args = dataChangedSpy.at(i);
        QVector<int> roles = args.at(2).value<QVector<int>>();
        if (!roles.isEmpty() &&
            !roles.contains(QQuickTreeModelAdaptor1::ModelIndexRole))
            continue;

        const QModelIndex topLeft = args.at(0).value<QModelIndex>();
        const QModelIndex bottomRight = args.at(1).value<QModelIndex>();
        for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
            emittedChanges.insert(row);
        }
    }

    QCOMPARE(emittedChanges, expectedRowChanges);
}

void tst_QQuickTreeModelAdaptor::reparentOnSameRow()
{
    TestModel model(2, 1);
    model.alternateChildlessRows = false;
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    const QModelIndex &destParent = model.index(0, 0);
    const QModelIndex &sourceParent = QModelIndex();
    QVERIFY(destParent.isValid());
    tma.expand(destParent);
    QVERIFY(tma.isExpanded(destParent));

    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    QSignalSpy rowsMovedSpy(&tma, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
    QVERIFY(rowsMovedSpy.isValid());
    QVERIFY(dataChangedSpy.isValid());

    QVERIFY(model.moveRows(sourceParent, 1, 1, destParent, 2));

    QModelIndex movedIndex = tma.index(3, 0, QModelIndex());
    QVERIFY(movedIndex.isValid());
    QCOMPARE(movedIndex.data(QQuickTreeModelAdaptor1::DepthRole).toInt(), 1);
    QCOMPARE(tma.data(movedIndex, QQuickTreeModelAdaptor1::ModelIndexRole).toModelIndex(), model.index(2, 0, destParent));

    // at least DepthRole and ModeIndexRole changes should have happened for the affected row
    bool depthChanged = false;
    bool modelIndexChanged = false;
    const QList<QList<QVariant> > &changes = dataChangedSpy;
    for (const QList<QVariant> &change : changes) {
        if (change.at(0) == movedIndex) {
            if (change.at(2).value<QVector<int> >().contains(QQuickTreeModelAdaptor1::DepthRole))
                depthChanged = true;
            if (change.at(2).value<QVector<int> >().contains(QQuickTreeModelAdaptor1::ModelIndexRole))
                modelIndexChanged = true;
        }
    }

    QCOMPARE(depthChanged, true);
    QCOMPARE(modelIndexChanged, true);

    QCOMPARE(rowsMovedSpy.count(), 0);

    model.moveRow(destParent, 2, QModelIndex(), 1);

    QCOMPARE(rowsMovedSpy.count(), 0);
    QVERIFY(tma.testConsistency());
    compareModels(tma, model);
}

void tst_QQuickTreeModelAdaptor::moveAllChildren()
{
    TestModel model(0, 1);
    model.alternateChildlessRows = false;
    model.fetchMore(QModelIndex());
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    /* Build this model:
     *   A
     *   B
     *   `-C
     */
    model.insertRows(0, 2, QModelIndex());
    QPersistentModelIndex aIndex(model.index(0, 0));
    QPersistentModelIndex bIndex(model.index(1, 0));
    model.insertRows(0, 1, bIndex);

    QCOMPARE(model.rowCount(QModelIndex()), 2);
    /* Expand B, then move C under A */
    tma.expandRow(1);


    QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
    QVERIFY(dataChangedSpy.isValid());

    QVERIFY(model.moveRows(bIndex, 0, 1, aIndex, 0));

    /* Check the outcome */
    QCOMPARE(tma.data(aIndex, QQuickTreeModelAdaptor1::HasChildrenRole).toBool(), true);
    QCOMPARE(tma.data(bIndex, QQuickTreeModelAdaptor1::HasChildrenRole).toBool(), false);
    QVERIFY(rowRoleWasChanged(dataChangedSpy, 0, QQuickTreeModelAdaptor1::HasChildrenRole));
    QVERIFY(rowRoleWasChanged(dataChangedSpy, 1, QQuickTreeModelAdaptor1::HasChildrenRole));
    dataChangedSpy.clear();

    /* Move C back into under B */
    QVERIFY(model.moveRows(aIndex, 0, 1, bIndex, 0));

    QCOMPARE(tma.data(aIndex, QQuickTreeModelAdaptor1::HasChildrenRole).toBool(), false);
    QCOMPARE(tma.data(bIndex, QQuickTreeModelAdaptor1::HasChildrenRole).toBool(), true);
    QVERIFY(rowRoleWasChanged(dataChangedSpy, 0, QQuickTreeModelAdaptor1::HasChildrenRole));
    QVERIFY(rowRoleWasChanged(dataChangedSpy, 1, QQuickTreeModelAdaptor1::HasChildrenRole));
    /* B must not be in expanded state, since it previously lost all its children */
    QCOMPARE(tma.data(bIndex, QQuickTreeModelAdaptor1::ExpandedRole).toBool(), false);

    dataChangedSpy.clear();
}

void tst_QQuickTreeModelAdaptor::selectionForRowRange()
{
    const int ModelRowCount = 9;
    const int ModelRowCountLoopStep = 4;

    TestModel model(ModelRowCount, 1);
    model.alternateChildlessRows = false;
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    // NOTE: Some selections may look a bit cryptic. Insert a call to
    // tma.dump() before each block if you need to see what's going on.

    for (int i = 0; i < ModelRowCount; i += ModelRowCountLoopStep) {
        // Single row selection
        const QModelIndex &idx = model.index(i, 0);
        const QItemSelection &sel = tma.selectionForRowRange(idx, idx);
        QCOMPARE(sel.count(), 1);
        const QItemSelectionRange &range = sel.first();
        QCOMPARE(QModelIndex(range.topLeft()), model.index(i, 0));
        QCOMPARE(QModelIndex(range.bottomRight()), model.index(i, 0));
    }

    for (int i = 0; i < ModelRowCount - ModelRowCountLoopStep; i += ModelRowCountLoopStep) {
        // Single range selection
        const QModelIndex &from = model.index(i, 0);
        const QModelIndex &to = model.index(i + ModelRowCountLoopStep, 0);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 1);
        const QItemSelectionRange &range = sel.first();
        QCOMPARE(QModelIndex(range.topLeft()), model.index(i, 0));
        QCOMPARE(QModelIndex(range.bottomRight()), model.index(i + ModelRowCountLoopStep, 0));
    }

    {   // Select all, no branch expanded
        const QModelIndex &from = model.index(0, 0);
        const QModelIndex &to = model.index(ModelRowCount - 1, 0);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 1);
        const QItemSelectionRange &range = sel.first();
        QCOMPARE(QModelIndex(range.topLeft()), model.index(0, 0));
        QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0));
    }

    // Expand 1st top-level item
    const QModelIndex &parent = model.index(0, 0);
    tma.expand(parent);

    {   // 1st item expanded, select first 5 rows
        const QModelIndex &from = tma.mapRowToModelIndex(0);
        const QModelIndex &to = tma.mapRowToModelIndex(4);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 2);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(0, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(0, 0));
            else if (range.topLeft() ==  model.index(0, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(3, 0, parent));
            else
                QFAIL("Unexpected selection range");
        }
    }

    {   // 1st item expanded, select first 5 top-level items
        const QModelIndex &from = tma.mapRowToModelIndex(0);
        const QModelIndex &to = tma.mapRowToModelIndex(4 + ModelRowCount);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 2);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(0, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(4, 0));
            else if (range.topLeft() ==  model.index(0, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent));
            else
                QFAIL("Unexpected selection range");
        }
    }

    // Expand 2nd top-level item
    const QModelIndex &parent2 = model.index(1, 0);
    tma.expand(parent2);

    {   // 1st two items expanded, select first 5 top-level items
        const QModelIndex &from = tma.mapRowToModelIndex(0);
        const QModelIndex &to = tma.mapRowToModelIndex(4 + 2 * ModelRowCount);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 3);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(0, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(4, 0));
            else if (range.topLeft() ==  model.index(0, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent));
            else if (range.topLeft() ==  model.index(0, 0, parent2))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent2));
            else
                QFAIL("Unexpected selection range");
        }
    }

    // Expand 1st child of 1st top-level item
    const QModelIndex &parent3 = model.index(0, 0, parent);
    tma.expand(parent3);

    {   // 1st two items, and 1st child of 1st item expanded, select first 5 rows
        const QModelIndex &from = tma.mapRowToModelIndex(0);
        const QModelIndex &to = tma.mapRowToModelIndex(4);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 3);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(0, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(0, 0));
            else if (range.topLeft() ==  model.index(0, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(0, 0, parent));
            else if (range.topLeft() ==  model.index(0, 0, parent3))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(2, 0, parent3));
            else
                QFAIL("Unexpected selection range");
        }
    }

    {   // 1st two items, and 1st child of 1st item expanded, select all
        const QModelIndex &from = tma.mapRowToModelIndex(0);
        const QModelIndex &to = tma.mapRowToModelIndex(4 * ModelRowCount - 1);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 4);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(0, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0));
            else if (range.topLeft() ==  model.index(0, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent));
            else if (range.topLeft() ==  model.index(0, 0, parent2))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent2));
            else if (range.topLeft() ==  model.index(0, 0, parent3))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent3));
            else
                QFAIL("Unexpected selection range");
        }
    }

    {   // 1st two items, and 1st child of 1st item expanded, select rows across branches
        const QModelIndex &from = tma.mapRowToModelIndex(8);
        const QModelIndex &to = tma.mapRowToModelIndex(23);
        const QItemSelection &sel = tma.selectionForRowRange(from, to);
        QCOMPARE(sel.count(), 4);
        // We don't know in which order the selection ranges are
        // being added, so we iterate and try to find what we expect.
        for (const QItemSelectionRange &range : sel) {
            if (range.topLeft() ==  model.index(1, 0))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(1, 0));
            else if (range.topLeft() ==  model.index(1, 0, parent))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent));
            else if (range.topLeft() ==  model.index(0, 0, parent2))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(3, 0, parent2));
            else if (range.topLeft() ==  model.index(6, 0, parent3))
                QCOMPARE(QModelIndex(range.bottomRight()), model.index(ModelRowCount - 1, 0, parent3));
            else
                QFAIL("Unexpected selection range");
        }
    }
}

void tst_QQuickTreeModelAdaptor::hasChildrenEmit()
{
    TestModel model(1, 1);
    model.alternateChildlessRows = false;
    QQuickTreeModelAdaptor1 tma;
    tma.setModel(&model);

    QModelIndex root = model.index(0,0);
    QVERIFY(root.isValid());

    QModelIndex child = model.index(0, 0, root);
    QVERIFY(child.isValid());

    // Root not expanded , child not expanded, insert in child, expect no datachanged
    {
        QVERIFY(!tma.isExpanded(root));
        QVERIFY(!tma.isExpanded(child));
        QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        QCOMPARE(dataChangedSpy.count(), 0);
        QCOMPARE(model.rowCount(child), 1);
        model.insertRow(1, child);
        QCOMPARE(model.rowCount(child), 2);
        QCOMPARE(dataChangedSpy.count(), 0);
    }

    // Root not expanded, insert in root, expect datachanged
    {
        QVERIFY(!tma.isExpanded(root));
        QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        QCOMPARE(dataChangedSpy.count(), 0);
        QCOMPARE(model.rowCount(root), 1);
        model.insertRow(1, root);
        QCOMPARE(model.rowCount(root), 2);
        QCOMPARE(dataChangedSpy.count(), 1);
    }

    // Root not expanded, child not expanded, remove in child, expect no datachanged
    {
        QVERIFY(!tma.isExpanded(root));
        QVERIFY(!tma.isExpanded(child));
        QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        QCOMPARE(dataChangedSpy.count(), 0);
        QCOMPARE(model.rowCount(child), 2);
        model.removeRow(1, child);
        QCOMPARE(model.rowCount(child), 1);
        QCOMPARE(dataChangedSpy.count(), 0);
    }

    // Root not expanded, remove in root, expected datachanged on hasChildren
    {
        QVERIFY(!tma.isExpanded(root));
        QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        QCOMPARE(dataChangedSpy.count(), 0);
        QCOMPARE(model.rowCount(root), 2);
        model.removeRow(1, root);
        QCOMPARE(model.rowCount(root), 1);
        QCOMPARE(dataChangedSpy.count(), 1);
    }
}

QTEST_MAIN(tst_QQuickTreeModelAdaptor)
#include "tst_qquicktreemodeladaptor.moc"
