File indexing completed on 2024-05-19 05:41:55

0001 // apptesting_fixture.cpp                                      -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #include <ct_lvtmdl_packagetreemodel.h>
0021 #include <kstandardaction.h>
0022 #include <mainwindow.h>
0023 
0024 #include <apptesting_fixture.h>
0025 
0026 #include <utility>
0027 
0028 #include <KActionCollection>
0029 #include <QComboBox>
0030 
0031 CodeVisApplicationTestFixture::CodeVisApplicationTestFixture()
0032 {
0033     Q_INIT_RESOURCE(resources);
0034     Q_INIT_RESOURCE(desktopapp);
0035 
0036     // Resources must be initialized before mainwindow, so I can't initialize this on
0037     // the initialization list.
0038     mainWindow = new TestMainWindow(sharedNodeStorage, &undoManager);
0039     mainWindow->show();
0040 }
0041 
0042 bool CodeVisApplicationTestFixture::hasDefaultTabWidget() const
0043 {
0044     return mainWindow->currentGraphTab != nullptr;
0045 }
0046 
0047 bool CodeVisApplicationTestFixture::isShowingWelcomePage() const
0048 {
0049     return mainWindow->ui.welcomePage->isVisible();
0050 }
0051 
0052 bool CodeVisApplicationTestFixture::isShowingGraphPage() const
0053 {
0054     return mainWindow->ui.graphPage->isVisible();
0055 }
0056 
0057 void CodeVisApplicationTestFixture::forceRelayout()
0058 {
0059     auto *currentTab = qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget());
0060     auto *view = currentTab->graphicsView();
0061     view->graphicsScene()->reLayout();
0062     QTest::qWait(500);
0063 }
0064 
0065 void CodeVisApplicationTestFixture::graphPressMoveRelease(QPoint source, QPoint destiny)
0066 {
0067     auto *graphTab = qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget());
0068 
0069     QTest::mousePress(graphTab->graphicsView()->viewport(),
0070                       Qt::MouseButton::LeftButton,
0071                       Qt::KeyboardModifier::NoModifier,
0072                       source);
0073     QTest::qWait(1000);
0074     QTest::mouseMove(graphTab->graphicsView()->viewport(), destiny);
0075     QTest::qWait(1000);
0076     QTest::mouseRelease(graphTab->graphicsView()->viewport(),
0077                         Qt::MouseButton::LeftButton,
0078                         Qt::KeyboardModifier::NoModifier,
0079                         destiny);
0080     QTest::qWait(1000);
0081 }
0082 
0083 void CodeVisApplicationTestFixture::clickOn(ClickableFeature const& feature)
0084 {
0085     auto *graphTab = qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget());
0086 
0087     for (auto *tool : graphTab->tools()) {
0088         tool->setProperty("debug", true);
0089     }
0090 
0091     auto newPackageVisitor = [&](Sidebar::ManipulationTool::NewPackage const& info) {
0092         auto *button = graphTab->ui->toolBox->getButtonNamed("Package");
0093         auto *action = dynamic_cast<ToolAddPackage *>(graphTab->tools()[TOOL_ADD_PACKAGE_ID]);
0094         auto *inputDialog = action->inputDialog();
0095         inputDialog->overrideExec([inputDialog, info] {
0096             auto *nameLineEdit = inputDialog->findChild<QLineEdit *>("name");
0097             nameLineEdit->setText(info.name);
0098             return true;
0099         });
0100         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0101     };
0102 
0103     auto newComponentVisitor = [&](Sidebar::ManipulationTool::NewComponent const& info) {
0104         auto *button = graphTab->ui->toolBox->getButtonNamed("Component");
0105         auto *action = dynamic_cast<ToolAddComponent *>(graphTab->tools()[TOOL_ADD_COMPONENT_ID]);
0106         auto *inputDialog = action->inputDialog();
0107         inputDialog->overrideExec([inputDialog, info] {
0108             auto *nameLineEdit = inputDialog->findChild<QLineEdit *>("name");
0109             nameLineEdit->setText(info.name);
0110             return true;
0111         });
0112         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0113     };
0114 
0115     auto newLogicalEntityVisitor = [&](Sidebar::ManipulationTool::NewLogicalEntity const& info) {
0116         auto *button = graphTab->ui->toolBox->getButtonNamed("Logical Entity");
0117         auto *action = dynamic_cast<ToolAddLogicalEntity *>(graphTab->tools()[TOOL_ADD_LOGICAL_ENTITY_ID]);
0118         auto *inputDialog = action->inputDialog();
0119         inputDialog->overrideExec([inputDialog, info] {
0120             auto *nameLineEdit = inputDialog->findChild<QLineEdit *>("name");
0121             nameLineEdit->setText(info.name);
0122             auto *kindLineEdit = inputDialog->findChild<QComboBox *>("kind");
0123             kindLineEdit->setCurrentText(info.kind);
0124             return true;
0125         });
0126         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0127     };
0128 
0129     auto addDependencyVisitor = [&](Sidebar::ManipulationTool::AddDependency) {
0130         auto *button = graphTab->ui->toolBox->getButtonNamed("Physical Dependency");
0131         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0132     };
0133 
0134     auto addIsAVisitor = [&](Sidebar::ManipulationTool::AddIsA) {
0135         auto *button = graphTab->ui->toolBox->getButtonNamed("Is A");
0136         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0137     };
0138 
0139     auto resetZoomVisitor = [&](Sidebar::VisualizationTool::ResetZoom) {
0140         auto *button = graphTab->ui->toolBox->getButtonNamed("Reset Zoom");
0141         QTest::mouseClick(button, Qt::MouseButton::LeftButton, Qt::KeyboardModifiers(), QPoint(), DEFAULT_QT_DELAY);
0142     };
0143 
0144     auto newProjectVisitor = [&](Menubar::File::NewProject) {
0145         mainWindow->actionCollection()->action("file_new")->trigger();
0146     };
0147 
0148     auto closeProjectVisitor = [&](Menubar::File::CloseProject) {
0149         mainWindow->actionCollection()->action("file_close")->trigger();
0150     };
0151 
0152     auto currentGraphInfoVisitor = [&](CurrentGraph info) {
0153         QTest::mousePress(graphTab->graphicsView()->viewport(),
0154                           Qt::MouseButton::LeftButton,
0155                           Qt::KeyboardModifiers(),
0156                           {info.x, info.y});
0157         QTest::qWait(5);
0158         QTest::mouseRelease(graphTab->graphicsView()->viewport(),
0159                             Qt::MouseButton::LeftButton,
0160                             Qt::KeyboardModifiers(),
0161                             {info.x, info.y});
0162     };
0163 
0164     auto packageVisitor = [&](PackageTreeView::Package const& pkg) {
0165         auto *model = mainWindow->packageModel;
0166         auto *packageTreeView = mainWindow->ui.packagesTree;
0167 
0168         // look for the item on the model.:
0169         QModelIndex idx;
0170         for (int i = 0; i < model->invisibleRootItem()->rowCount(); i++) {
0171             auto *item = model->invisibleRootItem()->child(i, 0);
0172             if (item->data(Codethink::lvtmdl::ModelRoles::e_QualifiedName).toString()
0173                 == QString::fromStdString(pkg.name)) {
0174                 idx = item->index();
0175             }
0176         }
0177         assert(idx.isValid());
0178         Q_EMIT packageTreeView->branchSelected(idx);
0179     };
0180 
0181     /* The Std::visit spec for the call:
0182     std::variant<Sidebar::ManipulationTool::NewPackage,
0183         Sidebar::ManipulationTool::NewComponent,
0184         Sidebar::ManipulationTool::NewLogicalEntity,
0185         Sidebar::ManipulationTool::AddDependency,
0186         Sidebar::ManipulationTool::AddIsA,
0187         Sidebar::VisualizationTool::ResetZoom,
0188         Menubar::File::NewProject,
0189         Menubar::File::CloseProject,
0190         PackageTreeView::Package,
0191         CurrentGraph
0192     >;
0193     */
0194     std::visit(
0195         visitor{
0196             newPackageVisitor,
0197             newComponentVisitor,
0198             newLogicalEntityVisitor,
0199             addDependencyVisitor,
0200             addIsAVisitor,
0201             resetZoomVisitor,
0202             newProjectVisitor,
0203             closeProjectVisitor,
0204             packageVisitor,
0205             currentGraphInfoVisitor,
0206         },
0207         feature);
0208 }
0209 
0210 void CodeVisApplicationTestFixture::ctrlZ()
0211 {
0212     QTest::keySequence(mainWindow, static_cast<QKeySequence>(static_cast<int>(Qt::CTRL) | static_cast<int>(Qt::Key_Z)));
0213     QTest::qWait(100);
0214 }
0215 
0216 void CodeVisApplicationTestFixture::ctrlShiftZ()
0217 {
0218 #if defined(Q_OS_WINDOWS)
0219     QTest::keySequence(mainWindow, static_cast<QKeySequence>(static_cast<int>(Qt::CTRL) | static_cast<int>(Qt::Key_Y)));
0220 #else
0221     QTest::keySequence(mainWindow,
0222                        static_cast<QKeySequence>(static_cast<int>(Qt::CTRL) | static_cast<int>(Qt::SHIFT)
0223                                                  | static_cast<int>(Qt::Key_Z)));
0224 #endif
0225     QTest::qWait(100);
0226 }
0227 
0228 bool CodeVisApplicationTestFixture::isAnyToolSelected()
0229 {
0230     auto *tool =
0231         qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget())->graphicsView()->currentTool();
0232     qDebug() << "The current tool is:" << (tool ? tool->name() : nullptr) << "View ptr: "
0233              << qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget())->graphicsView();
0234     return tool != nullptr;
0235 }
0236 
0237 LakosEntity *CodeVisApplicationTestFixture::findElement(const std::string& qualifiedName)
0238 {
0239     auto *currentTab = qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget());
0240     auto *view = currentTab->graphicsView();
0241     auto *entity = view->graphicsScene()->entityByQualifiedName(qualifiedName);
0242 
0243     assert(entity);
0244     return entity;
0245 }
0246 
0247 QPoint CodeVisApplicationTestFixture::findElementTopLeftPosition(const std::string& qname)
0248 {
0249     auto *entity = findElement(qname);
0250     auto *currentTab = qobject_cast<GraphTabElement *>(mainWindow->currentGraphTab->currentWidget());
0251     auto *view = currentTab->graphicsView();
0252 
0253     const auto offset = QPointF(10, 10);
0254     const auto p = entity->scenePos() + offset;
0255     return view->mapFromScene(p);
0256 }