testfwuis/symbianunittestui/qt/tabwidgettestrun.cpp
changeset 2 453d490c84a5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testfwuis/symbianunittestui/qt/tabwidgettestrun.cpp	Fri Sep 17 08:58:49 2010 +0300
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: TabWidget class to select, run tests and show the result.
+ *
+ */
+
+#include <QPushButton>
+#include <QWidget>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QTableWidget>
+#include <QGridLayout>
+#include <QLabel>
+#include <QProgressBar>
+#include <QPalette>
+#include <QTableWidgetItem>
+#include <QHeaderView>
+#include "tabwidgettestrun.h"
+#include "widgettestrunner.h"
+#include "settings.h"
+#include "testitemlist.h"
+#include "dialogmsg.h"
+
+static const QString TOTAL = "Total: %1";
+static const QString PASSED = "Passed: %1";
+static const QString FAILED = "Failed: %1";
+static const QString ERRORSUMMARY = "Error summary";
+static const QString NAME = "Case Name";
+static const QString REASON = "Reason";
+static const int FONTPIXELSIZE = 12;
+static const int FONTPIXELSIZE_ITEM = 15;
+static const int FONTPIXELSIZE_SUBITEM = 10;
+static const QString CASELIST = "Cases List";
+static const QString UNMARKED = "  ";
+static const QString MARKED = "* ";
+static const QString PARTIALLY_MARKED = "# ";
+static const int MARK_LEN = MARKED.length();
+static const QString CPP_SCOPE_OP = "::";
+static const QString EXPAND = "Expand";
+static const QString EXPAND_ALL = "Expand All";
+static const QString COLLAPSE = "Collapse";
+static const QString COLLAPSE_ALL = "Collapse All";
+
+TabWidgetTestRun::TabWidgetTestRun(QWidget* parent) :
+    QTabWidget(parent)
+    {
+    setContextMenuPolicy(Qt::NoContextMenu);
+    listTestItems = new TestItemList();
+    listSelectedTestItems = new TestItemList();
+    load();
+    dlgErrMsg = new DialogMsg(this);
+    connect(testRunner, SIGNAL(errorOccurred(const QString)), dlgErrMsg, SLOT(showMsg(const QString)));
+    }
+
+TabWidgetTestRun::~TabWidgetTestRun()
+    {
+    delete listTestItems;
+    listTestItems = NULL;
+    delete listSelectedTestItems;
+    listSelectedTestItems = NULL;
+    }
+
+void TabWidgetTestRun::createTestsTab()
+    {
+    tabTests = new QWidget(this);
+    createTreeWidgetTests();
+    this->addTab(tabTests, tr("Test Cases"));
+    }
+
+void TabWidgetTestRun::createExecutionTab()
+    {
+    tabRunner = new QTabWidget(this);
+    createExecutionWidgets();
+    this->addTab(tabRunner, tr("Execution"));
+    }
+
+void TabWidgetTestRun::createExecutionWidgets()
+    {
+    labelTotal = new QLabel(tabRunner);
+    labelTotal->setText(TOTAL.arg(0));
+    labelPassed = new QLabel(tabRunner);
+    labelPassed->setText(PASSED.arg(0));
+    labelFailed = new QLabel(tabRunner);
+    labelFailed->setText(FAILED.arg(0));
+
+    labelErrorSummary = new QLabel(tabRunner);
+    labelErrorSummary->setText(ERRORSUMMARY);
+    tblWdgtErrorSummary = new QTableWidget(tabRunner);
+    tblWdgtErrorSummary->setColumnCount(2);
+    tblWdgtErrorSummary->setColumnWidth(0, 200);
+
+    QTableWidgetItem* itemName = new QTableWidgetItem();
+    tblWdgtErrorSummary->setHorizontalHeaderItem(0, itemName);
+    QTableWidgetItem* itemReason = new QTableWidgetItem();
+    tblWdgtErrorSummary->setHorizontalHeaderItem(1, itemReason);
+    tblWdgtErrorSummary->horizontalHeaderItem(0)->setText(NAME);
+    tblWdgtErrorSummary->horizontalHeaderItem(1)->setText(REASON);
+    tblWdgtErrorSummary->setShowGrid(true);
+    tblWdgtErrorSummary->setSortingEnabled(false);
+    tblWdgtErrorSummary->horizontalHeader()->setStretchLastSection(true);
+    testRunner = new WidgetTestRunner(tabRunner);
+    testRunner->setHidden(true);
+    progressBarExecuting = new QProgressBar(tabRunner);
+    progressBarExecuting->setHidden(true);
+    }
+
+void TabWidgetTestRun::setTabPageExecutionLayout()
+    {
+    QWidget* labelsWidget = new QWidget(tabRunner);
+    QGridLayout* labelsLayout = new QGridLayout(tabRunner);
+
+    labelsLayout->addWidget(labelPassed, 0, 0);
+    labelsLayout->addWidget(labelFailed, 0, 1);
+    labelsLayout->addWidget(labelTotal, 0, 2);
+    labelsWidget->setLayout(labelsLayout);
+
+    QGridLayout* layout = new QGridLayout(tabRunner);
+    layout->addWidget(labelsWidget, 0, 0);
+    layout->addWidget(progressBarExecuting, 1, 0);
+    layout->addWidget(labelErrorSummary, 2, 0);
+    layout->addWidget(tblWdgtErrorSummary, 3, 0);
+    tabRunner->setLayout(layout);
+    }
+
+void TabWidgetTestRun::load()
+    {
+    createTestsTab();
+    setupTestsTabEventHandlers();
+    setTabPageTestsLayout();
+    createExecutionTab();
+    setTabPageExecutionLayout();
+    setupRunnerEventHandlers();
+    }
+
+void TabWidgetTestRun::createTreeWidgetTests()
+    {
+    treeWdgtTests = new QTreeWidget(tabTests);
+    treeWdgtTests->headerItem()->setText(0, CASELIST);
+    btnRun = new QPushButton(tr("Run"), tabTests);
+    btnExpandCollapse = new QPushButton(tr("Expand"), tabTests);
+    // Disable buttons on startup
+    btnRun->setEnabled(false);
+
+    btnExpandCollapse->setEnabled(false);
+    }
+
+void TabWidgetTestRun::setTabPageTestsLayout()
+    {
+    QWidget* btnsWidget = new QWidget(tabTests);
+    QGridLayout* btnsLayout = new QGridLayout(tabTests);
+    btnsLayout->addWidget(btnRun, 0, 0);
+    btnsLayout->addWidget(btnExpandCollapse, 0, 1);
+    btnsWidget->setLayout(btnsLayout);
+
+    QGridLayout* layout = new QGridLayout(tabTests);
+    layout->addWidget(treeWdgtTests, 0, 0);
+    layout->addWidget(btnsWidget, 1, 0);
+
+    tabTests->setLayout(layout);
+    }
+
+void TabWidgetTestRun::setTotal(int num)
+    {
+    labelTotal->setText(TOTAL.arg(num));
+    labelTotal->repaint();
+    }
+
+void TabWidgetTestRun::setPassed(int num)
+    {
+    labelPassed->setText(PASSED.arg(num));
+    labelPassed->repaint();
+    }
+
+void TabWidgetTestRun::setFailed(QString name, QString reason, int num)
+    {
+    labelFailed->setText(FAILED.arg(num));
+    labelFailed->repaint();
+    int curRow = tblWdgtErrorSummary->rowCount();
+    tblWdgtErrorSummary->insertRow(curRow);
+    QTableWidgetItem* itemName = new QTableWidgetItem(name);
+    QTableWidgetItem* itemReason = new QTableWidgetItem(reason);
+    tblWdgtErrorSummary->setItem(curRow, 0, itemName);
+    tblWdgtErrorSummary->setItem(curRow, 1, itemReason);
+    QFont font;
+    font.setPixelSize(FONTPIXELSIZE);
+    itemName->setFont(font);
+    itemReason->setFont(font);
+    }
+
+void TabWidgetTestRun::resetTreeWidget()
+    {
+    for(int i = treeWdgtTests->topLevelItemCount() -1; i >= 0; --i)
+        {
+        delete treeWdgtTests->topLevelItem(i);
+        }
+    treeWdgtTests->clear();
+    }
+
+void TabWidgetTestRun::resetTestItemList()
+    {
+    listTestItems->removeAll();
+    listSelectedTestItems->removeAll();
+    }
+
+void TabWidgetTestRun::addTests(QStringList testCases)
+    {
+    resetTestItemList();
+    resetTreeWidget();
+    QFont font, subItemFont;
+    font.setPixelSize(FONTPIXELSIZE_ITEM);
+    subItemFont.setPixelSize(FONTPIXELSIZE_SUBITEM);
+    QStringList fetchedCaseNames;
+    QTreeWidgetItem* item = NULL;
+    QTreeWidgetItem* subItem = NULL;
+    foreach (QString dllName, testCases)
+            {
+            if (listTestItems->exists(dllName))
+                {
+                continue;
+                }
+            
+            fetchedCaseNames.clear();
+            if (testRunner->listTestCases(dllName, fetchedCaseNames) != 0)
+                {
+                continue;
+                }
+            item = new QTreeWidgetItem(treeWdgtTests);
+            item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable
+                    | Qt::ItemIsEnabled);
+            item->setText(0, UNMARKED + dllName);
+            item->setFont(0, font);
+            
+            foreach(QString testCase, fetchedCaseNames)
+                    {
+                    subItem = new QTreeWidgetItem(item);
+                    subItem->setText(0, UNMARKED + testCase/*getFuncName(testCase)*/);
+                    subItem->setFont(0, subItemFont);
+                    }
+            listTestItems->addItemExclusively(dllName, fetchedCaseNames);
+            }
+
+    if (treeWdgtTests->topLevelItemCount() > 0)
+        {
+        treeWdgtTests->setCurrentItem(treeWdgtTests->topLevelItem(0));
+        treeWdgtTests->resizeColumnToContents(0);
+        if (this->currentWidget() != tabTests)
+            {
+            this->setCurrentWidget(tabTests);
+            }
+        treeWdgtTests->setFocus();
+        btnRun->setEnabled(false);
+        btnExpandCollapse->setEnabled(true);
+        emit this->testsAdded();
+        }
+    }
+
+QString TabWidgetTestRun::getFuncName(const QString& caseName)
+    {
+    int index = caseName.indexOf(CPP_SCOPE_OP, 0);
+    return caseName.right(caseName.length() - index - CPP_SCOPE_OP.length());
+    }
+
+void TabWidgetTestRun::setupRunnerEventHandlers()
+    {
+    connect(this, SIGNAL(currentChanged(int)), this,
+            SLOT(changeCurrentTab(int)));
+    connect(btnRun, SIGNAL(clicked()), this, SLOT(runTests()));
+    connect(btnExpandCollapse, SIGNAL(clicked()), this,
+            SLOT(expandCollapseItem()));
+    connect(this, SIGNAL(testRun()), testRunner, SLOT(runTests()));
+    connect(testRunner, SIGNAL(testExecuted(int)), progressBarExecuting,
+            SLOT(setValue(int)));
+    connect(testRunner, SIGNAL(testPassed(int)), this, SLOT(setPassed(int)));
+    connect(testRunner, SIGNAL(testFailed(QString, QString, int)), this,
+            SLOT(setFailed(QString, QString, int)));
+    }
+
+void TabWidgetTestRun::runTests()
+    {
+    if (this->currentWidget() != tabRunner)
+        {
+        this->setCurrentWidget(tabRunner);
+        }
+    tblWdgtErrorSummary->clearContents();
+    tblWdgtErrorSummary->setRowCount(0);
+    testRunner->addTestDllNames(listSelectedTestItems->items());
+    testRunner->addTestCaseNames(listSelectedTestItems->subItems());
+    progressBarExecuting->setEnabled(true);
+    progressBarExecuting->show();
+    progressBarExecuting->setMaximum(
+            listSelectedTestItems->subItems().count());
+    progressBarExecuting->setValue(0);
+    labelTotal->setText(TOTAL.arg(listSelectedTestItems->subItems().count()));
+    labelPassed->setText(PASSED.arg(0));
+    labelFailed->setText(FAILED.arg(0));
+    emit this->testRun();
+    progressBarExecuting->setEnabled(false);
+    }
+
+void TabWidgetTestRun::changeCurrentTab(int index)
+    {
+    if (this->widget(index) == tabTests)
+        {
+        treeWdgtTests->setFocus();
+        emit this->currentTabChangedToTests(!listTestItems->empty());
+        }
+    else
+        {
+        tblWdgtErrorSummary->setFocus();
+        emit this->currentTabChangedToExecution();
+        }
+    }
+
+void TabWidgetTestRun::setupTestsTabEventHandlers()
+    {
+    connect(treeWdgtTests, SIGNAL(itemClicked(QTreeWidgetItem* , int)), this,
+            SLOT(selectDeselectTestCases(QTreeWidgetItem* , int)));
+    connect(treeWdgtTests,
+            SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+            this, SLOT(changeCurItem(QTreeWidgetItem*, QTreeWidgetItem*)));
+    connect(treeWdgtTests, SIGNAL(itemExpanded(QTreeWidgetItem*)), this,
+            SLOT(setBtnExpandCollapseEnabled(QTreeWidgetItem*)));
+    connect(treeWdgtTests, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this,
+            SLOT(setBtnExpandCollapseEnabled(QTreeWidgetItem*)));
+    }
+
+void TabWidgetTestRun::changeCurItem(QTreeWidgetItem* cur, QTreeWidgetItem*/* prev*/)
+    {
+    if (cur != NULL)
+        {
+        setBtnExpandCollapseEnabled(cur);
+        emit this->selectedTestsChanged(listSelectedTestItems->empty(),
+                isAllCasesSelected(),
+                cur->text(treeWdgtTests->currentColumn()).contains(MARKED));
+        }
+    }
+
+void TabWidgetTestRun::selectCurrentCase()
+    {
+    QString itemName = treeWdgtTests->currentItem()->text(
+            treeWdgtTests->currentColumn());
+    if (itemName.contains(UNMARKED))
+        {
+        selectDeselectTestCases(treeWdgtTests->currentItem(),
+                treeWdgtTests->currentColumn());
+        }
+    }
+
+void TabWidgetTestRun::selectAllCases()
+    {
+    for (int i = 0; i < treeWdgtTests->topLevelItemCount(); ++i)
+        {
+        QString itemName = treeWdgtTests->topLevelItem(i)->text(
+                treeWdgtTests->currentColumn());
+        if (itemName.contains(UNMARKED)
+                || itemName.contains(PARTIALLY_MARKED))
+            {
+            // Deselect current first
+            if (itemName.contains(PARTIALLY_MARKED))
+                {
+                deselectCase(treeWdgtTests->topLevelItem(i),
+                        treeWdgtTests->currentColumn());
+                }
+            selectDeselectTestCases(treeWdgtTests->topLevelItem(i),
+                    treeWdgtTests->currentColumn());
+            }
+        }
+    }
+
+void TabWidgetTestRun::deselectCase(QTreeWidgetItem* item, int column)
+    {
+    QString itemName = item->text(column);
+    if (itemName.contains(MARKED) || itemName.contains(PARTIALLY_MARKED))
+        {
+        selectDeselectTestCases(item, column);
+        }
+    }
+
+void TabWidgetTestRun::deselectCurrentCase()
+    {
+    deselectCase(treeWdgtTests->currentItem(), treeWdgtTests->currentColumn());
+    }
+
+void TabWidgetTestRun::deselectAllCases()
+    {
+    for (int i = 0; i < treeWdgtTests->topLevelItemCount(); ++i)
+        {
+        QString itemName = treeWdgtTests->topLevelItem(i)->text(
+                treeWdgtTests->currentColumn());
+        if (itemName.contains(MARKED) || itemName.contains(PARTIALLY_MARKED))
+            {
+            selectDeselectTestCases(treeWdgtTests->topLevelItem(i),
+                    treeWdgtTests->currentColumn());
+            }
+        }
+    }
+
+void TabWidgetTestRun::saveSettings(const Settings* settings)
+    {
+    testRunner->saveSettings(settings);
+    }
+
+QString& TabWidgetTestRun::removeMark(QString& src)
+    {
+    return src.remove(MARKED).remove(UNMARKED).remove(PARTIALLY_MARKED);
+    }
+
+void TabWidgetTestRun::selectDeselectTestCases(QTreeWidgetItem* item,
+        int column)
+    {
+    QString itemName = item->text(column);
+    QTreeWidgetItem* subItem;
+    QString subName;
+    if (treeWdgtTests->indexOfTopLevelItem(item) != -1)
+        {
+        // Top level item
+        // Marked. Unmark them.        
+        if (itemName.contains(MARKED) || itemName.contains(PARTIALLY_MARKED))
+            {
+            item->setText(column, itemName.replace(0, MARK_LEN, UNMARKED));
+            listSelectedTestItems->removeItem(removeMark(itemName));
+            for (int i = 0; i < item->childCount(); ++i)
+                {
+                subItem = item->child(i);
+                subName = subItem->text(column);
+                if (subName.contains(MARKED))
+                    {
+                    subItem->setText(column, subName.replace(0, MARK_LEN,
+                            UNMARKED));
+                    }
+                }
+            }
+        // Unmarked. Mark them.
+        else
+            {
+            QStringList subNames;
+            for (int i = 0; i < item->childCount(); ++i)
+                {
+                subItem = item->child(i);
+                subName = subItem->text(column);
+                subItem->setText(column, subName.replace(0, MARK_LEN, MARKED));
+                subNames << removeMark(subName);
+                }
+            item->setText(column, itemName.replace(0, MARK_LEN, MARKED));
+            listSelectedTestItems->addItemExclusively(removeMark(itemName),
+                    subNames);
+            }
+        }
+    else
+        {
+        // Child item
+        // Marked. Unmark it.
+        QTreeWidgetItem* parentItem = item->parent();
+        QString parentItemName = parentItem->text(column);
+        if (itemName.contains(MARKED))
+            {
+            item->setText(column, itemName.replace(0, MARK_LEN, UNMARKED));
+            listSelectedTestItems->removeOneSubItem(
+                    removeMark(parentItemName), removeMark(itemName));
+            int i = 0;
+            for (; i < parentItem->childCount(); ++i)
+                {
+                if (parentItem->child(i)->text(column).contains(MARKED))
+                    {
+                    parentItem->setText(column,
+                            parentItem->text(column).replace(0, MARK_LEN,
+                                    PARTIALLY_MARKED));
+                    break;
+                    }
+                }
+            if (i == parentItem->childCount())
+                {
+                parentItem->setText(column, parentItem->text(column).replace(
+                        0, MARK_LEN, UNMARKED));
+                }
+            }
+        // Unmakred. Mark it.
+        else
+            {
+            item->setText(column, itemName.replace(0, MARK_LEN, MARKED));
+            listSelectedTestItems->addOneSubItem(removeMark(parentItemName),
+                    removeMark(itemName));
+            int i = 0;
+            for (; i < parentItem->childCount(); ++i)
+                {
+                if (parentItem->child(i)->text(column).contains(UNMARKED))
+                    break;
+                }
+            if (i < parentItem->childCount())
+                {
+                parentItem->setText(column, parentItem->text(column).replace(
+                        0, MARK_LEN, PARTIALLY_MARKED));
+                }
+            else
+                {
+                parentItem->setText(column, parentItem->text(column).replace(
+                        0, MARK_LEN, MARKED));
+                }
+            }
+        }
+    btnRun->setEnabled(!listSelectedTestItems->empty());
+    emit this->selectedTestsChanged(listSelectedTestItems->empty(),
+            isAllCasesSelected(), item->text(column).contains(MARKED));
+    }
+
+void TabWidgetTestRun::setBtnExpandCollapseEnabled(QTreeWidgetItem* item)
+    {
+    if (treeWdgtTests->indexOfTopLevelItem(item) == -1)
+        {
+        btnExpandCollapse->setEnabled(false);
+        }
+    else
+        {
+        btnExpandCollapse->setEnabled(true);
+        if (item == treeWdgtTests->currentItem())
+            {
+            btnExpandCollapse->setText(item->isExpanded() ? COLLAPSE : EXPAND);
+            }
+        }
+    }
+
+void TabWidgetTestRun::expandCollapseItem()
+    {
+    QTreeWidgetItem* cur = treeWdgtTests->currentItem();
+    cur->setExpanded(!cur->isExpanded());
+    btnExpandCollapse->setText(cur->isExpanded() ? COLLAPSE : EXPAND);
+    }
+
+bool TabWidgetTestRun::isAllCasesSelected()
+    {
+    return listSelectedTestItems->isEqual(listTestItems);
+    }
+
+void TabWidgetTestRun::pressLeftArrow()
+    {
+    // TODO
+    }
+
+void TabWidgetTestRun::pressRightArrow()
+    {
+    // TODO
+    }
+
+void TabWidgetTestRun::pressUpArrow()
+    {
+    // TODO
+    }
+
+void TabWidgetTestRun::pressDownArrow()
+    {
+    // TODO
+    }
+
+void TabWidgetTestRun::pressEnter()
+    {
+    // TODO
+    }