//-----------------------------------------------------------------------------
// File: tst_ComponentParameterModel.cpp
//-----------------------------------------------------------------------------
// Project: Kactus 2
// Author: Esko Pekkarinen
// Date: 13.01.2015
//
// Description:
// Unit test for class ComponentParameterModel.
//-----------------------------------------------------------------------------

#include <QtTest>

#include <QModelIndex>
#include <QVariant>

#include <editors/ComponentEditor/parameters/ComponentParameterModel.h>
#include <editors/ComponentEditor/parameters/ComponentParameterColumns.h>

#include <KactusAPI/include/IPXactSystemVerilogParser.h>

#include <KactusAPI/include/ComponentParameterFinder.h>

#include <IPXACTmodels/Component/Component.h>
#include <IPXACTmodels/common/Parameter.h>

class tst_ComponentParameterModel : public QObject
{
    Q_OBJECT

public:
    tst_ComponentParameterModel();

private slots:
    void testHasRowForEachTopLevelParameter();
    void testHasRowForEachTopLevelParameter_data();     
    void testHasColumnForNameAndId();
    void testFunctionAsValue();

private:
    ComponentParameterModel* make(QSharedPointer<Component> component);
};

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::()
//-----------------------------------------------------------------------------
tst_ComponentParameterModel::tst_ComponentParameterModel()
{

}

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::testHasRowForEachTopLevelParameter()
//-----------------------------------------------------------------------------
void tst_ComponentParameterModel::testHasRowForEachTopLevelParameter()
{
    QFETCH(int, parameterCount);

    QList<QSharedPointer<Parameter> > parameters;

    for (int i = 0; i < parameterCount; i++)
    {
        parameters.append(QSharedPointer<Parameter>(new Parameter()));
    }

    QSharedPointer<Component> component(new Component(VLNV(), Document::Revision::Std14));
    component->getParameters()->append(parameters);

    ComponentParameterModel* model = make(component);

    QCOMPARE(model->rowCount(), parameterCount);
}

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::testHasRowForEachTopLevelParameter_data()
//-----------------------------------------------------------------------------
void tst_ComponentParameterModel::testHasRowForEachTopLevelParameter_data()
{
    QTest::addColumn<int>("parameterCount");

    QTest::newRow("no parameters") << 0;
    QTest::newRow("single parameter") << 1;
    QTest::newRow("multiple parameters") << 4;
}

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::testHasColumnForNameValueAndId()
//-----------------------------------------------------------------------------
void tst_ComponentParameterModel::testHasColumnForNameAndId()
{
    QSharedPointer<Parameter> testParameter(new Parameter());
    testParameter->setName("testParameter");
    testParameter->setValueId("testId");
    testParameter->setValue("1");

    QList<QSharedPointer<Parameter> > parameters;
    parameters.append(testParameter);
   
    QSharedPointer<Component> component(new Component(VLNV(), Document::Revision::Std14));
    component->getParameters()->append(parameters);

    ComponentParameterModel* model = make(component);

    QCOMPARE(model->columnCount(), 2);
    QCOMPARE(model->data(model->index(0, ComponentParameterColumns::NAME)).toString(), QString("testParameter"));
    QCOMPARE(model->data(model->index(0, ComponentParameterColumns::ID)).toString(), QString("testId"));

    QCOMPARE(model->data(QModelIndex()).toString(), QString(""));
    QCOMPARE(model->data(model->index(42, ComponentParameterColumns::NAME)).toString(), QString(""));
}

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::testFunctionAsValue()
//-----------------------------------------------------------------------------
void tst_ComponentParameterModel::testFunctionAsValue()
{
    QSharedPointer<Parameter> testParameter(new Parameter());
    testParameter->setName("testParameter");
    testParameter->setValueId("testId");
    testParameter->setValue("1+1");

    QList<QSharedPointer<Parameter> > parameters;
    parameters.append(testParameter);

    QSharedPointer<Component> component(new Component(VLNV(), Document::Revision::Std14));
    component->getParameters()->append(parameters);

    ComponentParameterModel* model = make(component);

    QCOMPARE(model->data(model->index(0, ComponentParameterColumns::NAME)).toString(), QString("testParameter"));
    QCOMPARE(model->data(model->index(0, ComponentParameterColumns::ID)).toString(), QString("testId"));
}

//-----------------------------------------------------------------------------
// Function: tst_ComponentParameterModel::make()
//-----------------------------------------------------------------------------
ComponentParameterModel* tst_ComponentParameterModel::make(QSharedPointer<Component> component)
{
    QSharedPointer<ParameterFinder> parameterFinder(new ComponentParameterFinder(component));

    ComponentParameterModel* model = new ComponentParameterModel(parameterFinder, this);
    
    QSharedPointer<ExpressionParser> parser(new IPXactSystemVerilogParser(parameterFinder));
    model->setExpressionParser(parser);
    
    return model;
}

QTEST_APPLESS_MAIN(tst_ComponentParameterModel)

#include "tst_ComponentParameterModel.moc"
