/***************************************************************************
 * SPDX-FileCopyrightText: 2024 S. MANKOWSKI stephane@mankowski.fr
 * SPDX-FileCopyrightText: 2024 G. DE BURE support@mankowski.fr
 * SPDX-License-Identifier: GPL-3.0-or-later
 ***************************************************************************/
/** @file
 * This file is a test script.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgtestmacro.h"

/**
 * To check the progress
 */
static int previousProgress = 0;

/**
 * To test progress
 * @param iPos the current position
 * @return 0
 */
int progress1(int iPos, qint64 /*iTime*/, const QString& /*iName*/, void* /*iData*/)
{
    if (previousProgress > iPos) {
        return 1;
    }
    previousProgress = iPos;
    return 0;
}

/**
 * To test progress
 * @param iPos the current position
 * @return 1
 */
int progress2(int iPos, qint64 /*iTime*/, const QString& /*iName*/, void* /*iData*/)
{
    if (iPos > 50) {
        return 1;
    }
    return 0;
}
/**
 * The main function of the unit test
 * @param argc the number of arguments
 * @param argv the list of arguments
 */
int main(int argc, char** argv)
{
    Q_UNUSED(argc)
    Q_UNUSED(argv)

    // Init test
    SKGINITTEST(true)

    // test class SKGDocument / COMMIT / ROLLBACK
    {
        SKGDocument document1;
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction(transaction1)"), document1.beginTransaction(QLatin1String("transaction1")), false)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.initialize"), document1.initialize(), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction(transaction1)"), document1.beginTransaction(QLatin1String("transaction1")), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
        SKGTESTERROR(QLatin1String("TRANS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction(transaction2)"), document1.beginTransaction(QLatin1String("transaction2")), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
        SKGTESTERROR(QLatin1String("TRANS.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("TRANS.endTransaction"), document1.endTransaction(true), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.endTransaction TOO MANY !"), document1.endTransaction(true), false)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)

        // Test rollback
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction"), document1.beginTransaction(QLatin1String("transaction3")), true)
        SKGTESTERROR(QLatin1String("TRANS.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("TRANS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("TRANS.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL1"))

        // Test multi transaction in cascade
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction"), document1.beginTransaction(QLatin1String("transaction4")), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
        SKGTESTERROR(QLatin1String("TRANS.beginTransaction"), document1.beginTransaction(QLatin1String("transaction'5")), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 2)
        SKGTESTERROR(QLatin1String("TRANS.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("TRANS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
        SKGTEST(QLatin1String("TRANS.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL2"))
        SKGTESTERROR(QLatin1String("TRANS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
        SKGTEST(QLatin1String("TRANS.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL1"))

        SKGPropertyObject prop(&document1);
        SKGTESTERROR(QLatin1String("PROP.getParameter"), prop.setName(QLatin1String("ATT1")), true)
        SKGTESTERROR(QLatin1String("PROP.load"), prop.load(), true)
        SKGTEST(QLatin1String("PROP.getValue"), prop.getValue(), QLatin1String("VAL1"))
        prop.getParentId();

        SKGPropertyObject prop2(prop);
        SKGPropertyObject prop3(static_cast<SKGObjectBase>(prop));
        SKGPropertyObject prop4;
        prop4 = static_cast<SKGObjectBase>(prop);
    }

    // test class SKGDocument / COMMIT / ROLLBACK with SKGTransactionMng
    {
        // Test with a succeeded transaction
        SKGError err;
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("TRANSMNG.initialize()"), document1.initialize(), true)
        SKGTEST(QLatin1String("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0) {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("T1"), err)

            // The code here
            IFOK(err) {
                SKGTEST(QLatin1String("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 1)

                // Example; an error is generated
                err = SKGError(1, QLatin1String("Error1"));
            }

            // A rollback is done here because the scope is close
        }
        SKGTESTERROR(QLatin1String("TRANSMNG.err"), err, false)
        SKGTEST(QLatin1String("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0)
        SKGTEST(QLatin1String("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 0)
    }

    {
        // Test with a succeeded transaction
        SKGError err;
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("TRANSMNG.initialize()"), document1.initialize(), true)
        SKGTEST(QLatin1String("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0) {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("T1"), err)

            // The code here
            IFOK(err) {
                SKGTEST(QLatin1String("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 1)

                // Example; transaction succeeded
                SKGTESTERROR(QLatin1String("TRANS.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2")), true)
            }

            // A commit is done here because the scope is close
        }
        SKGTESTERROR(QLatin1String("TRANSMNG.err"), err, true)
        SKGTEST(QLatin1String("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 1)
        SKGTEST(QLatin1String("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 0)
    }

    {
        // Test undo on parameters
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("TRANSUNDO.initialize()"), document1.initialize(), true)
        SKGError err;
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String(""))

        {
            // In a scope to the then endTransaction automatically
            SKGBEGINTRANSACTION(document1, QLatin1String("T1"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL1_1")), true)  // To test undo on more than one modification of an object in a transaction
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL1_2")), true)  // To test undo on more than one modification of an object in a transaction
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL1")), true)
        }
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL1"))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)

        {
            // In a scope to the then endTransaction automatically
            SKGBEGINTRANSACTION(document1, QLatin1String("T2"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2_1")), true)  // To test undo on more than one modification of an object in a transaction
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2_2")), true)  // To test undo on more than one modification of an object in a transaction

            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT1"), QLatin1String("VAL2")), true)
        }
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL2"))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 2)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)

        QStringList oResult;
        int nbitemexpected = 6;
        SKGTESTERROR(QLatin1String("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QLatin1String("doctransactionitem"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)

        SKGTESTERROR(QLatin1String("TRANSUNDO.undoRedoTransaction(T2, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL1"))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 1)

        SKGTESTERROR(QLatin1String("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QLatin1String("doctransactionitem"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)

        SKGTESTERROR(QLatin1String("TRANSUNDO.undoRedoTransaction(T1, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String(""))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 0)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 2)

        SKGTESTERROR(QLatin1String("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QLatin1String("doctransactionitem"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)

        SKGTESTERROR(QLatin1String("TRANSUNDO.undoRedoTransaction(T1, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL1"))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 1)

        SKGTESTERROR(QLatin1String("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QLatin1String("doctransactionitem"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)

        SKGTESTERROR(QLatin1String("TRANSUNDO.undoRedoTransaction(T2, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTEST(QLatin1String("TRANSUNDO.getParameter"), document1.getParameter(QLatin1String("ATT1")), QLatin1String("VAL2"))
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 2)
        SKGTEST(QLatin1String("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)
        SKGTESTERROR(QLatin1String("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QLatin1String("doctransactionitem"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
    }

    {
        // Test max depth for transaction
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("MAXDEPTH.initialize()"), document1.initialize(), true)
        SKGError err;
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 0) {
            SKGBEGINTRANSACTION(document1, QLatin1String("MAXDEPTH 1"), err)
            SKGTESTERROR(QLatin1String("MAXDEPTH.setParameter"), document1.setParameter(QLatin1String("SKG_UNDO_MAX_DEPTH"), QLatin1String("3")), true)
        }
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 1) {
            SKGBEGINTRANSACTION(document1, QLatin1String("MAXDEPTH 2"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        SKGTESTERROR(QLatin1String("MAXDEPTH.endTransaction"), err, true)
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 2) {
            SKGBEGINTRANSACTION(document1, QLatin1String("MAXDEPTH 3"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        SKGTESTERROR(QLatin1String("MAXDEPTH.endTransaction"), err, true)
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3) {
            SKGBEGINTRANSACTION(document1, QLatin1String("MAXDEPTH 4"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        SKGTESTERROR(QLatin1String("MAXDEPTH.endTransaction"), err, true)
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3) {
            SKGBEGINTRANSACTION(document1, QLatin1String("MAXDEPTH 5"), err)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
            SKGTESTERROR(QLatin1String("TRANSUNDO.setParameter"), document1.setParameter(QLatin1String("ATT5"), QLatin1String("VAL")), true)
        }
        SKGTESTERROR(QLatin1String("MAXDEPTH.endTransaction"), err, true)
        SKGTEST(QLatin1String("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3)

        SKGDocument::SKGObjectModificationList oModifications;
        SKGTESTERROR(QLatin1String("MAXDEPTH.getModifications"), document1.getModifications(document1.getTransactionToProcess(SKGDocument::UNDO), oModifications), true)
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.count"), oModifications.count(), 2)
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.id"), oModifications[0].id, 7)
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.table"), oModifications[0].table, QLatin1String("parameters"))
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.type"), static_cast<unsigned int>(oModifications[0].type), static_cast<unsigned int>(SKGDocument::U))
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.id"), oModifications[1].id, 8)
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.table"), oModifications[1].table, QLatin1String("parameters"))
        SKGTEST(QLatin1String("MAXDEPTH.oModifications.type"), static_cast<unsigned int>(oModifications[1].type), static_cast<unsigned int>(SKGDocument::I))
    }

    {
        // Redo delete after new transaction
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("REDO.initialize()"), document1.initialize(), true)
        SKGError err;
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 0) {
            SKGBEGINTRANSACTION(document1, QLatin1String("SKGDocument::REDO 1"), err)
            SKGTESTERROR(QLatin1String("REDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        {
            SKGBEGINTRANSACTION(document1, QLatin1String("SKGDocument::REDO 2"), err)
            SKGTESTERROR(QLatin1String("REDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        {
            SKGBEGINTRANSACTION(document1, QLatin1String("SKGDocument::REDO 3"), err)
            SKGTESTERROR(QLatin1String("REDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        {
            SKGBEGINTRANSACTION(document1, QLatin1String("SKGDocument::REDO 4"), err)
            SKGTESTERROR(QLatin1String("REDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 4)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)

        SKGTESTERROR(QLatin1String("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)

        SKGTESTERROR(QLatin1String("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 2)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)

        SKGTESTERROR(QLatin1String("REDO.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)

        SKGTESTERROR(QLatin1String("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 2)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)

        {
            SKGBEGINTRANSACTION(document1, QLatin1String("SKGDocument::REDO 5"), err)
            SKGTESTERROR(QLatin1String("REDO.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        }

        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)

        SKGTESTERROR(QLatin1String("REDO.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDOLASTSAVE), true)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(), 0)
        SKGTEST(QLatin1String("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
    }

    {
        // Test progress
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("PROGRESS.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("PROGRESS.setProgressCallback"), document1.setProgressCallback(&progress1, nullptr), true)
        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("PROGRESS1"), 5), true)
        for (int i = 1; i <= 5; ++i) {
            SKGTESTERROR(QLatin1String("PROGRESS.stepForward"), document1.stepForward(i), true)
            SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("PROGRESS2"), 3), true)
            for (int j = 1; j <= 3; j++) {
                SKGTESTERROR(QLatin1String("PROGRESS.stepForward"), document1.stepForward(j), true)
            }
            SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)
        }
        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("PROGRESS.setProgressCallback"), document1.setProgressCallback(&progress2, nullptr), true)
        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("PROGRESS1"), 5), true)
        for (int i = 1; i <= 5; ++i) {
            SKGTESTERROR(QLatin1String("PROGRESS.stepForward"), document1.stepForward(i), (i < 3))
            SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("PROGRESS2"), 3), (i < 3))
            for (int j = 1; j <= 3; j++) {
                SKGTESTERROR(QLatin1String("PROGRESS.stepForward"), document1.stepForward(j), (3 * i + j - 3 < 5))
            }
            SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)
        }
        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)
    }

    {
        // Test progress
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("PROGRESS.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)

        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)
        SKGTEST(QLatin1String("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 1)

        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(true), true)
        SKGTEST(QLatin1String("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)

        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("T3")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)

        // Transaction failed with existing name
        SKGTESTERROR(QLatin1String("PROGRESS.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        SKGTESTERROR(QLatin1String("PROGRESS.endTransaction"), document1.endTransaction(false), true)
        SKGTEST(QLatin1String("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)
    }

    {
        // Test group of transactions on U
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("GROUP.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T3")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL3")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T4")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL4")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.groupTransactions("), document1.groupTransactions(3, 5), true)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(), 2)
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTEST(QLatin1String("GROUP.getParameter"), document1.getParameter(QLatin1String("ATT")), QLatin1String("VAL1"))

        // Remove all transaction
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 1)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
        SKGTESTERROR(QLatin1String("GROUP.removeAllTransactions"), document1.removeAllTransactions(), true)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 0)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)
    }

    {
        // Test group of transactions on R
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("GROUP.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T3")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL3")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T4")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL4")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)

        SKGTESTERROR(QLatin1String("GROUP.groupTransactions("), document1.groupTransactions(7, 9), true)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
//      document1.dump(DUMPTRANSACTIONS);
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTEST(QLatin1String("GROUP.getParameter"), document1.getParameter(QLatin1String("ATT")), QLatin1String("VAL3"))
    }

    {
        // Test group of transactions on U and R
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("GROUP.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T3")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL3")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T4")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL4")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)

        SKGTESTERROR(QLatin1String("GROUP.groupTransactions("), document1.groupTransactions(3, 6), false)
//      document1.dump(DUMPTRANSACTIONS);
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 2)
        SKGTEST(QLatin1String("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
    }

    {
        // Test group of transactions on R
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("GROUP.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        QString filename1 = SKGTest::getTestPath(QLatin1String("OUT")) % "/filename1.skg";
        SKGTESTERROR(QLatin1String("GROUP.saveAs"), document1.saveAs(filename1, true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T3")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL3")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("GROUP.beginTransaction"), document1.beginTransaction(QLatin1String("T4")), true)
        SKGTESTERROR(QLatin1String("GROUP.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL4")), true)
        SKGTESTERROR(QLatin1String("GROUP.endTransaction"), document1.endTransaction(true), true)

        document1.dump(DUMPTRANSACTIONS);
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDOLASTSAVE), true)
        SKGTEST(QLatin1String("GROUP.getParameter"), document1.getParameter(QLatin1String("ATT")), QLatin1String("VAL2"))
        SKGTESTERROR(QLatin1String("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
        SKGTEST(QLatin1String("GROUP.getParameter"), document1.getParameter(QLatin1String("ATT")), QLatin1String("VAL4"))

        QStringList oResult;
        SKGTESTERROR(QLatin1String("SKGServices::dumpSelectSqliteOrder"), document1.dumpSelectSqliteOrder(QLatin1String("SELECT * from doctransaction"), oResult), true)
        SKGTESTERROR(QLatin1String("SKGServices::dumpSelectSqliteOrder"), document1.dumpSelectSqliteOrder(QLatin1String("SELECT * from doctransaction")), true)
    }

    {
        // Test error
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("ERROR.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("ERROR.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDO), false)  // No transaction

        SKGTESTERROR(QLatin1String("ERROR.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTEST(QLatin1String("ERROR.getCurrentTransaction"), document1.getCurrentTransaction(), 2)

        SKGTESTERROR(QLatin1String("ERROR.groupTransactions"), document1.groupTransactions(1, 1), false)  // Not authorized into a transaction
        SKGTESTERROR(QLatin1String("ERROR.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDO), false)  // Not authorized into a transaction
        SKGTESTERROR(QLatin1String("ERROR.saveAs"), document1.saveAs(SKGTest::getTestPath(QLatin1String("OUT")) % "/filename1.skg", true), false)  // Not authorized into a transaction

        SKGTESTERROR(QLatin1String("ERROR.endTransaction"), document1.endTransaction(true), true)
    }

    {
        // Test messages
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("MSG.initialize()"), document1.initialize(), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Information"), SKGDocument::Information), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Warning"), SKGDocument::Warning), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Positive"), SKGDocument::Positive), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Error"), SKGDocument::Error), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Hidden"), SKGDocument::Hidden), true)

        SKGTESTERROR(QLatin1String("MSG.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("MSG.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL")), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("Hello")), true)
        SKGTESTERROR(QLatin1String("MSG.sendMessage"), document1.sendMessage(QLatin1String("World")), true)
        SKGTESTERROR(QLatin1String("MSG.endTransaction"), document1.endTransaction(true), true)

        SKGDocument::SKGMessageList msg;
        SKGTESTERROR(QLatin1String("MSG.getMessages"), document1.getMessages(document1.getTransactionToProcess(SKGDocument::UNDO), msg), true)
        SKGTEST(QLatin1String("MSG.msg.count"), msg.count(), 6)
        SKGTEST(QLatin1String("MSG.msg"), msg.at(0).Text, QLatin1String("Information")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(0).Type), static_cast<unsigned int>(SKGDocument::Information))
        SKGTEST(QLatin1String("MSG.msg"), msg.at(1).Text, QLatin1String("Warning")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(1).Type), static_cast<unsigned int>(SKGDocument::Warning))
        SKGTEST(QLatin1String("MSG.msg"), msg.at(2).Text, QLatin1String("Positive")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(2).Type), static_cast<unsigned int>(SKGDocument::Positive))
        SKGTEST(QLatin1String("MSG.msg"), msg.at(3).Text, QLatin1String("Error")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(3).Type), static_cast<unsigned int>(SKGDocument::Error))
        SKGTEST(QLatin1String("MSG.msg"), msg.at(4).Text, QLatin1String("Hello")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(4).Type), static_cast<unsigned int>(SKGDocument::Information))
        SKGTEST(QLatin1String("MSG.msg"), msg.at(5).Text, QLatin1String("World")); SKGTEST(QLatin1String("MSG.type"), static_cast<unsigned int>(msg.at(5).Type), static_cast<unsigned int>(SKGDocument::Information))
    }

    {
        // Test clean after save
        SKGDocument document1;
        SKGTESTERROR(QLatin1String("CLEAN.initialize()"), document1.initialize(), true)

        SKGTESTERROR(QLatin1String("CLEAN.beginTransaction"), document1.beginTransaction(QLatin1String("T1")), true)
        SKGTESTERROR(QLatin1String("CLEAN.setParameter"), document1.setParameter(QLatin1String("SKG_UNDO_CLEAN_AFTER_SAVE"), QLatin1String("Y")), true)
        SKGTESTERROR(QLatin1String("CLEAN.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL1")), true)
        SKGTESTERROR(QLatin1String("CLEAN.endTransaction"), document1.endTransaction(true), true)

        SKGTESTERROR(QLatin1String("CLEAN.beginTransaction"), document1.beginTransaction(QLatin1String("T2")), true)
        SKGTESTERROR(QLatin1String("CLEAN.setParameter"), document1.setParameter(QLatin1String("ATT"), QLatin1String("VAL2")), true)
        SKGTESTERROR(QLatin1String("CLEAN.endTransaction"), document1.endTransaction(true), true)

        SKGTEST(QLatin1String("CLEAN.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 2)

        QString filename1 = SKGTest::getTestPath(QLatin1String("OUT")) % "/filename1.skg";
        SKGTESTERROR(QLatin1String("CLEAN.saveAs"), document1.saveAs(filename1, true), true)
        SKGTEST(QLatin1String("CLEAN.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 0)
    }
    // End test
    SKGENDTEST()
}
