/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/UnitTests/TestFramework/Framework/Qt/qtTestModel.cpp
598 строк
17 KB
Ingrater
Clang-format fixes and update to 18.1.1 (#1234)
10 мар 2024, 15:51
Не верифицирован
10 мар 2024, 15:51
2f16acf
Код
Авторство
О чём код?
#include <TestFramework/TestFrameworkPCH.h> #ifdef EZ_USE_QT # include <QApplication> # include <QPalette> # include <TestFramework/Framework/Qt/qtTestModel.h> //////////////////////////////////////////////////////////////////////// // ezQtTestModelEntry public functions //////////////////////////////////////////////////////////////////////// ezQtTestModelEntry::ezQtTestModelEntry(const ezTestFrameworkResult* pResult, ezInt32 iTestIndex, ezInt32 iSubTestIndex) : m_pResult(pResult) , m_iTestIndex(iTestIndex) , m_iSubTestIndex(iSubTestIndex) { } ezQtTestModelEntry::~ezQtTestModelEntry() { ClearEntries(); } void ezQtTestModelEntry::ClearEntries() { for (ezInt32 i = (ezInt32)m_SubEntries.size() - 1; i >= 0; --i) { delete m_SubEntries[i]; } m_SubEntries.clear(); } ezUInt32 ezQtTestModelEntry::GetNumSubEntries() const { return (ezInt32)m_SubEntries.size(); } ezQtTestModelEntry* ezQtTestModelEntry::GetSubEntry(ezUInt32 uiIndex) const { if (uiIndex >= GetNumSubEntries()) return nullptr; return m_SubEntries[uiIndex]; } void ezQtTestModelEntry::AddSubEntry(ezQtTestModelEntry* pEntry) { pEntry->m_pParentEntry = this; pEntry->m_uiIndexInParent = (ezUInt32)m_SubEntries.size(); m_SubEntries.push_back(pEntry); } ezQtTestModelEntry::ezTestModelEntryType ezQtTestModelEntry::GetNodeType() const { return (m_iTestIndex == -1) ? RootNode : ((m_iSubTestIndex == -1) ? TestNode : SubTestNode); } const ezTestResultData* ezQtTestModelEntry::GetTestResult() const { switch (GetNodeType()) { case ezQtTestModelEntry::TestNode: case ezQtTestModelEntry::SubTestNode: return &m_pResult->GetTestResultData(m_iTestIndex, m_iSubTestIndex); default: return nullptr; } } static QColor ToneColor(const QColor& inputColor, const QColor& toneColor) { qreal fHue = toneColor.hueF(); qreal fSaturation = 1.0f; qreal fLightness = inputColor.lightnessF(); fLightness = ezMath::Clamp(fLightness, 0.20, 0.80); return QColor::fromHslF(fHue, fSaturation, fLightness); } //////////////////////////////////////////////////////////////////////// // ezQtTestModel public functions //////////////////////////////////////////////////////////////////////// ezQtTestModel::ezQtTestModel(QObject* pParent, ezQtTestFramework* pTestFramework) : QAbstractItemModel(pParent) , m_pTestFramework(pTestFramework) , m_Root(nullptr) { QPalette palette = QApplication::palette(); m_pResult = &pTestFramework->GetTestResult(); // Derive state colors from the current active palette. m_SucessColor = ToneColor(palette.text().color(), QColor(Qt::green)).toRgb(); m_FailedColor = ToneColor(palette.text().color(), QColor(Qt::red)).toRgb(); m_CustomStatusColor = ToneColor(palette.text().color(), QColor(Qt::yellow)).toRgb(); m_TestColor = ToneColor(palette.base().color(), QColor(Qt::cyan)).toRgb(); m_SubTestColor = ToneColor(palette.base().color(), QColor(Qt::blue)).toRgb(); m_TestIcon = QIcon(":/Icons/Icons/pie.png"); m_TestIconOff = QIcon(":/Icons/Icons/pie_off.png"); UpdateModel(); } ezQtTestModel::~ezQtTestModel() { m_Root.ClearEntries(); } void ezQtTestModel::Reset() { beginResetModel(); endResetModel(); } void ezQtTestModel::InvalidateAll() { dataChanged(QModelIndex(), QModelIndex()); } void ezQtTestModel::TestDataChanged(ezInt32 iTestIndex, ezInt32 iSubTestIndex) { QModelIndex TestModelIndex = index(iTestIndex, 0); // Invalidate whole test row Q_EMIT dataChanged(TestModelIndex, index(iTestIndex, columnCount() - 1)); // Invalidate all sub-tests const ezQtTestModelEntry* pEntry = (ezQtTestModelEntry*)TestModelIndex.internalPointer(); ezInt32 iChildren = (ezInt32)pEntry->GetNumSubEntries(); Q_EMIT dataChanged(index(0, 0, TestModelIndex), index(iChildren - 1, columnCount() - 1, TestModelIndex)); } //////////////////////////////////////////////////////////////////////// // ezQtTestModel QAbstractItemModel functions //////////////////////////////////////////////////////////////////////// QVariant ezQtTestModel::data(const QModelIndex& index, int iRole) const { if (!index.isValid()) return QVariant(); const ezQtTestModelEntry* pEntry = (ezQtTestModelEntry*)index.internalPointer(); const ezQtTestModelEntry* pParentEntry = pEntry->GetParentEntry(); const ezQtTestModelEntry::ezTestModelEntryType entryType = pEntry->GetNodeType(); const ezInt32 iExecutingTest = m_pTestFramework->GetCurrentTestIndex(); const ezInt32 iExecutingSubTest = m_pTestFramework->GetCurrentSubTestIndex(); const bool bIsExecuting = pEntry->GetTestIndex() == iExecutingTest && pEntry->GetSubTestIndex() == iExecutingSubTest; bool bTestEnabled = true; bool bParentEnabled = true; bool bIsSubTest = entryType == ezQtTestModelEntry::SubTestNode; const std::string& testUnavailableReason = m_pTestFramework->IsTestAvailable(bIsSubTest ? pParentEntry->GetTestIndex() : pEntry->GetTestIndex()); if (bIsSubTest) { bTestEnabled = m_pTestFramework->IsSubTestEnabled(pEntry->GetTestIndex(), pEntry->GetSubTestIndex()); bParentEnabled = m_pTestFramework->IsTestEnabled(pParentEntry->GetTestIndex()); } else { bTestEnabled = m_pTestFramework->IsTestEnabled(pEntry->GetTestIndex()); } const ezTestResultData& TestResult = *pEntry->GetTestResult(); if (bIsExecuting && iRole == Qt::BackgroundRole) { return QColor(115, 100, 40); } // Name if (index.column() == Columns::Name) { switch (iRole) { case Qt::DisplayRole: { return QString(TestResult.m_sName.c_str()); } case Qt::CheckStateRole: { return bTestEnabled ? Qt::Checked : Qt::Unchecked; } case Qt::DecorationRole: { return (bTestEnabled && bParentEnabled) ? m_TestIcon : m_TestIconOff; } case Qt::ForegroundRole: { if (!testUnavailableReason.empty()) { QPalette palette = QApplication::palette(); return palette.color(QPalette::Disabled, QPalette::Text); } } case Qt::ToolTipRole: { if (!testUnavailableReason.empty()) { return QString("Test not available: %1").arg(testUnavailableReason.c_str()); } } default: return QVariant(); } } // Status else if (index.column() == Columns::Status) { switch (iRole) { case Qt::DisplayRole: { if (!testUnavailableReason.empty()) { return QString("Test not available: %1").arg(testUnavailableReason.c_str()); } else if (bTestEnabled && bParentEnabled) { if (bIsSubTest) { return QString("Enabled"); } else { // Count sub-test status const ezUInt32 iSubTests = m_pResult->GetSubTestCount(pEntry->GetTestIndex()); const ezUInt32 iEnabled = m_pTestFramework->GetSubTestEnabledCount(pEntry->GetTestIndex()); if (iEnabled == iSubTests) { return QString("All Enabled"); } return QString("%1 / %2 Enabled").arg(iEnabled).arg(iSubTests); } } else { return QString("Disabled"); } } case Qt::TextAlignmentRole: { return Qt::AlignRight; } default: return QVariant(); } } // Duration else if (index.column() == Columns::Duration) { switch (iRole) { case Qt::DisplayRole: { return QLocale(QLocale::English).toString(TestResult.m_fTestDuration, 'f', 4); } case Qt::TextAlignmentRole: { return Qt::AlignRight; } /*case Qt::BackgroundRole: { QPalette palette = QApplication::palette(); return palette.alternateBase().color(); }*/ case UserRoles::Duration: { if (bIsSubTest && TestResult.m_bExecuted) { return TestResult.m_fTestDuration / pParentEntry->GetTestResult()->m_fTestDuration; } else if (TestResult.m_bExecuted) { return TestResult.m_fTestDuration / m_pTestFramework->GetTotalTestDuration(); } return QVariant(); } case UserRoles::DurationColor: { if (TestResult.m_bExecuted) { return (bIsSubTest ? m_SubTestColor : m_TestColor); } return QVariant(); } default: return QVariant(); } } // Errors else if (index.column() == Columns::Errors) { switch (iRole) { case Qt::DisplayRole: { return QString("%1 / %2") .arg(m_pResult->GetErrorMessageCount(pEntry->GetTestIndex(), pEntry->GetSubTestIndex())) .arg(m_pResult->GetOutputMessageCount(pEntry->GetTestIndex(), pEntry->GetSubTestIndex())); } case Qt::BackgroundRole: { QPalette palette = QApplication::palette(); return palette.alternateBase().color(); } case Qt::ForegroundRole: { if (TestResult.m_bExecuted) { return (m_pResult->GetErrorMessageCount(pEntry->GetTestIndex(), pEntry->GetSubTestIndex()) == 0) ? m_SucessColor : m_FailedColor; } return QVariant(); } case Qt::TextAlignmentRole: { return Qt::AlignRight; } default: return QVariant(); } } // Assert Count else if (index.column() == Columns::Asserts) { switch (iRole) { case Qt::DisplayRole: { return QString("%1").arg(TestResult.m_iTestAsserts); } case Qt::BackgroundRole: { QPalette palette = QApplication::palette(); return palette.alternateBase().color(); } case Qt::TextAlignmentRole: { return Qt::AlignRight; } default: return QVariant(); } } // Progress else if (index.column() == Columns::Progress) { switch (iRole) { case Qt::DisplayRole: { if (!testUnavailableReason.empty()) { return QString("Test not available: %1").arg(testUnavailableReason.c_str()); } else if (bTestEnabled && bParentEnabled) { if (bIsSubTest) { if (TestResult.m_bExecuted) { return (TestResult.m_bSuccess) ? QString("Passed") : QString("Failed"); } else { if (!TestResult.m_sCustomStatus.empty()) { return QString(TestResult.m_sCustomStatus.c_str()); } return QString("Pending"); } } else { // Count sub-test status const ezUInt32 iEnabled = m_pTestFramework->GetSubTestEnabledCount(pEntry->GetTestIndex()); const ezUInt32 iExecuted = m_pResult->GetSubTestCount(pEntry->GetTestIndex(), ezTestResultQuery::Executed); const ezUInt32 iSucceeded = m_pResult->GetSubTestCount(pEntry->GetTestIndex(), ezTestResultQuery::Success); if (TestResult.m_bExecuted && iExecuted == iEnabled) { return (TestResult.m_bSuccess && iExecuted == iSucceeded) ? QString("Passed") : QString("Failed"); } else { return QString("%1 / %2 Executed").arg(iExecuted).arg(iEnabled); } } } else { return QString("Disabled"); } } case Qt::BackgroundRole: { QPalette palette = QApplication::palette(); return palette.alternateBase().color(); } case Qt::ForegroundRole: { if (!testUnavailableReason.empty()) { QPalette palette = QApplication::palette(); return palette.color(QPalette::Disabled, QPalette::Text); } else if (TestResult.m_bExecuted) { return TestResult.m_bSuccess ? m_SucessColor : m_FailedColor; } else if (!TestResult.m_sCustomStatus.empty()) { return m_CustomStatusColor; } return QVariant(); } case Qt::TextAlignmentRole: { return Qt::AlignRight; } default: return QVariant(); } } return QVariant(); } Qt::ItemFlags ezQtTestModel::flags(const QModelIndex& index) const { if (!index.isValid()) return Qt::ItemFlags(); ezQtTestModelEntry* pEntry = (ezQtTestModelEntry*)index.internalPointer(); if (pEntry == &m_Root) return Qt::ItemFlags(); return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; } QVariant ezQtTestModel::headerData(int iSection, Qt::Orientation orientation, int iRole) const { if (orientation == Qt::Horizontal && iRole == Qt::DisplayRole) { switch (iSection) { case Columns::Name: return QString("Name"); case Columns::Status: return QString("Status"); case Columns::Duration: return QString("Duration (ms)"); case Columns::Errors: return QString("Errors / Output"); case Columns::Asserts: return QString("Checks"); case Columns::Progress: return QString("Progress"); } } return QVariant(); } QModelIndex ezQtTestModel::index(int iRow, int iColumn, const QModelIndex& parent) const { if (!hasIndex(iRow, iColumn, parent)) return QModelIndex(); const ezQtTestModelEntry* pParent = nullptr; if (!parent.isValid()) pParent = &m_Root; else pParent = static_cast<ezQtTestModelEntry*>(parent.internalPointer()); ezQtTestModelEntry* pEntry = pParent->GetSubEntry(iRow); return pEntry ? createIndex(iRow, iColumn, pEntry) : QModelIndex(); } QModelIndex ezQtTestModel::parent(const QModelIndex& index) const { if (!index.isValid()) return QModelIndex(); ezQtTestModelEntry* pChild = static_cast<ezQtTestModelEntry*>(index.internalPointer()); ezQtTestModelEntry* pParent = pChild->GetParentEntry(); if (pParent == &m_Root) return QModelIndex(); return createIndex(pParent->GetIndexInParent(), 0, pParent); } int ezQtTestModel::rowCount(const QModelIndex& parent) const { if (parent.column() > 0) return 0; const ezQtTestModelEntry* pParent = nullptr; if (!parent.isValid()) pParent = &m_Root; else pParent = static_cast<ezQtTestModelEntry*>(parent.internalPointer()); return pParent->GetNumSubEntries(); } int ezQtTestModel::columnCount(const QModelIndex& parent) const { return Columns::ColumnCount; } bool ezQtTestModel::setData(const QModelIndex& index, const QVariant& value, int iRole) { ezQtTestModelEntry* pEntry = static_cast<ezQtTestModelEntry*>(index.internalPointer()); if (pEntry == nullptr || index.column() != Columns::Name || iRole != Qt::CheckStateRole) return false; if (pEntry->GetNodeType() == ezQtTestModelEntry::TestNode) { m_pTestFramework->SetTestEnabled(pEntry->GetTestIndex(), value.toBool()); TestDataChanged(pEntry->GetIndexInParent(), -1); // if a test gets enabled in the UI, and all sub-tests are currently disabled, // enable all sub-tests as well // if some set of sub-tests is already enabled and some are disabled, // do not mess with the user's choice of enabled tests bool bEnableSubTests = value.toBool(); for (ezUInt32 subIdx = 0; subIdx < pEntry->GetNumSubEntries(); ++subIdx) { if (m_pTestFramework->IsSubTestEnabled(pEntry->GetTestIndex(), subIdx)) { bEnableSubTests = false; break; } } if (bEnableSubTests) { for (ezUInt32 subIdx = 0; subIdx < pEntry->GetNumSubEntries(); ++subIdx) { m_pTestFramework->SetSubTestEnabled(pEntry->GetTestIndex(), subIdx, true); TestDataChanged(pEntry->GetIndexInParent(), subIdx); } } } else { m_pTestFramework->SetSubTestEnabled(pEntry->GetTestIndex(), pEntry->GetSubTestIndex(), value.toBool()); TestDataChanged(pEntry->GetParentEntry()->GetIndexInParent(), pEntry->GetIndexInParent()); } return true; } //////////////////////////////////////////////////////////////////////// // ezQtTestModel public slots //////////////////////////////////////////////////////////////////////// void ezQtTestModel::UpdateModel() { m_Root.ClearEntries(); if (m_pResult == nullptr) return; const ezUInt32 uiTestCount = m_pResult->GetTestCount(); for (ezUInt32 uiTestIndex = 0; uiTestIndex < uiTestCount; ++uiTestIndex) { ezQtTestModelEntry* pTestModelEntry = new ezQtTestModelEntry(m_pResult, uiTestIndex); m_Root.AddSubEntry(pTestModelEntry); const ezUInt32 uiSubTestCount = m_pResult->GetSubTestCount(uiTestIndex); for (ezUInt32 uiSubTestIndex = 0; uiSubTestIndex < uiSubTestCount; ++uiSubTestIndex) { ezQtTestModelEntry* pSubTestModelEntry = new ezQtTestModelEntry(m_pResult, uiTestIndex, uiSubTestIndex); pTestModelEntry->AddSubEntry(pSubTestModelEntry); } } // reset(); } #endif