File indexing completed on 2024-05-12 05:52:03

0001 /*
0002     SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include "kate_view_mgmt_tests.h"
0007 #include "katemainwindow.h"
0008 #include "kateviewspace.h"
0009 #include "ktexteditor_utils.h"
0010 
0011 #include <KLocalizedString>
0012 #include <KTextEditor/Editor>
0013 
0014 #include <QCommandLineParser>
0015 #include <QPointer>
0016 #include <QSignalSpy>
0017 #include <QTest>
0018 
0019 QTEST_MAIN(KateViewManagementTests)
0020 
0021 static bool viewspaceContainsView(KateViewSpace *vs, KTextEditor::View *v)
0022 {
0023     return vs->hasDocument(v->document());
0024 }
0025 
0026 static int tabIdxForDoc(QTabBar *t, KTextEditor::Document *d)
0027 {
0028     Q_ASSERT(t);
0029     for (int i = 0; i < t->count(); ++i) {
0030         if (t->tabData(i).value<DocOrWidget>().doc() == d)
0031             return i;
0032     }
0033     return -1;
0034 }
0035 
0036 static void clearAllDocs(KateMainWindow *mw)
0037 {
0038     auto vm = mw->viewManager();
0039     vm->slotCloseOtherViews();
0040     auto vs = vm->activeViewSpace();
0041     // close everything
0042     for (int i = 0; i < vs->numberOfRegisteredDocuments(); ++i) {
0043         vm->slotDocumentClose();
0044     }
0045 }
0046 
0047 KateViewManagementTests::KateViewManagementTests(QObject *)
0048 {
0049     // ensure ui file can be found and the translation domain is set to avoid warnings
0050     qApp->setApplicationName(QStringLiteral("kate"));
0051     KLocalizedString::setApplicationDomain(QByteArrayLiteral("kate"));
0052 
0053     m_tempdir = new QTemporaryDir;
0054     QVERIFY(m_tempdir->isValid());
0055 
0056     // ensure we use some dummy config
0057     KConfig::setMainConfigName(m_tempdir->path() + QStringLiteral("/testconfigfilerc"));
0058 
0059     // create KWrite variant to avoid plugin loading!
0060     static QCommandLineParser parser;
0061     app = std::make_unique<KateApp>(parser, KateApp::ApplicationKWrite, m_tempdir->path());
0062 }
0063 
0064 void KateViewManagementTests::testSingleViewspaceDoesntCloseWhenLastViewClosed()
0065 {
0066     app->sessionManager()->sessionNew();
0067     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0068 
0069     // Test that if we have 1 viewspaces then
0070     // closing the last view doesn't close the viewspace
0071 
0072     auto mw = app->activeKateMainWindow();
0073     auto vm = mw->viewManager();
0074 
0075     // Initially we have one viewspace and one view
0076     QCOMPARE(vm->m_views.size(), 1);
0077     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0078 
0079     // close active view
0080     vm->closeView(vm->activeView());
0081 
0082     // still same
0083     QCOMPARE(vm->m_views.size(), 0);
0084     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0085 }
0086 
0087 void KateViewManagementTests::testViewspaceClosesWhenLastViewClosed()
0088 {
0089     app->sessionManager()->sessionNew();
0090     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0091 
0092     // Test that if we have greater than 1 viewspaces then
0093     // closing the last view in a viewspace closes that view
0094     // space
0095 
0096     auto mw = app->activeKateMainWindow();
0097     auto vm = mw->viewManager();
0098 
0099     // Initially we have one viewspace
0100     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0101 
0102     vm->slotSplitViewSpaceVert();
0103 
0104     // Now we have two
0105     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0106     // and two views, one in each viewspace
0107     QCOMPARE(vm->m_views.size(), 2);
0108 
0109     // close active view
0110     vm->closeView(vm->activeView());
0111 
0112     QCOMPARE(vm->m_views.size(), 1);
0113     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0114 }
0115 
0116 void KateViewManagementTests::testViewspaceClosesWhenThereIsWidget()
0117 {
0118     app->sessionManager()->sessionNew();
0119     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0120 
0121     // Test that if we have greater than 1 viewspaces then
0122     // closing the last view in a viewspace closes that view
0123     // space
0124 
0125     KateMainWindow *mw = app->activeKateMainWindow();
0126     auto vm = mw->viewManager();
0127     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0128 
0129     vm->slotSplitViewSpaceVert();
0130     // Now we have two viewspaces
0131     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0132     auto *leftVS = vm->m_viewSpaceList[0];
0133     auto *rightVS = vm->m_viewSpaceList[1];
0134     QCOMPARE(rightVS, vm->activeViewSpace());
0135 
0136     // add a widget
0137     QPointer<QWidget> widget = new QWidget;
0138     Utils::addWidget(widget, app->activeMainWindow());
0139     // active viewspace remains the same
0140     QCOMPARE(vm->m_viewSpaceList[1], vm->activeViewSpace());
0141     // the widget should be active in activeViewSpace
0142     QCOMPARE(vm->activeViewSpace()->currentWidget(), widget);
0143     // activeView() should be nullptr
0144     QVERIFY(!vm->activeView());
0145 
0146     // there should still be 2 views
0147     // widget is not counted in views
0148     QCOMPARE(vm->m_views.size(), 2);
0149 
0150     const auto sortedViews = vm->views();
0151     QCOMPARE(sortedViews.size(), 2);
0152 
0153     // ensure we know where both of the views are and
0154     // we close the right one
0155     QVERIFY(viewspaceContainsView(rightVS, sortedViews.at(0)));
0156     QVERIFY(viewspaceContainsView(leftVS, sortedViews.at(1)));
0157 
0158     // Make the KTE::view in right viewspace active
0159     vm->activateView(sortedViews.at(0));
0160     QVERIFY(vm->activeView() == sortedViews.at(0));
0161 
0162     // close active view
0163     vm->closeView(vm->activeView());
0164 
0165     // one view left, but two viewspaces
0166     QCOMPARE(vm->m_views.size(), 1);
0167     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0168 
0169     // close the widget!
0170     QVERIFY(vm->removeWidget(widget));
0171     QTest::qWait(100);
0172     QVERIFY(!widget); // widget should be gone
0173 
0174     // only one viewspace should be left now
0175     QCOMPARE(vm->m_views.size(), 1);
0176     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0177 }
0178 
0179 void KateViewManagementTests::testMoveViewBetweenViewspaces()
0180 {
0181     app->sessionManager()->sessionNew();
0182     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0183 
0184     KateMainWindow *mw = app->activeKateMainWindow();
0185     auto vm = mw->viewManager();
0186     vm->slotSplitViewSpaceVert();
0187 
0188     // we have two viewspaces with 2 views
0189     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0190     QCOMPARE(vm->m_views.size(), 2);
0191 
0192     auto src = vm->activeViewSpace();
0193     auto dest = vm->m_viewSpaceList.front();
0194     QVERIFY(src != dest);
0195     vm->moveViewToViewSpace(dest, src, vm->activeView()->document());
0196     qApp->processEvents();
0197 
0198     // after moving we should have 2 views but only one viewspace left
0199     QCOMPARE(vm->m_viewSpaceList.size(), 1);
0200     QCOMPARE(vm->m_views.size(), 2);
0201 }
0202 
0203 void KateViewManagementTests::testTwoMainWindowsCloseInitialDocument1()
0204 {
0205     app->sessionManager()->sessionNew();
0206     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0207 
0208     // get first main window
0209     KateMainWindow *first = app->activeKateMainWindow();
0210     QVERIFY(first);
0211 
0212     // create a second one
0213     std::unique_ptr<KateMainWindow> second(app->newMainWindow());
0214     QVERIFY(second);
0215 
0216     // close the initial document
0217     QVERIFY(app->closeDocument(first->viewManager()->activeView()->document()));
0218 
0219     // create a new document, this did crash due to empty view space
0220     second->viewManager()->slotDocumentNew();
0221 }
0222 
0223 void KateViewManagementTests::testTwoMainWindowsCloseInitialDocument2()
0224 {
0225     app->sessionManager()->sessionNew();
0226     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0227 
0228     // get first main window
0229     KateMainWindow *first = app->activeKateMainWindow();
0230     QVERIFY(first);
0231 
0232     // create a second one
0233     std::unique_ptr<KateMainWindow> second(app->newMainWindow());
0234     QVERIFY(second);
0235 
0236     // close the initial document tab in second window
0237     second->viewManager()->activeViewSpace()->closeDocument(first->viewManager()->activeView()->document());
0238 
0239     // create a new document, this did crash due to empty view space
0240     second->viewManager()->slotDocumentNew();
0241 }
0242 
0243 void KateViewManagementTests::testTwoMainWindowsCloseInitialDocument3()
0244 {
0245     app->sessionManager()->sessionNew();
0246     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0247 
0248     // get first main window
0249     KateMainWindow *first = app->activeKateMainWindow();
0250     QVERIFY(first);
0251 
0252     // create a second one
0253     std::unique_ptr<KateMainWindow> second(app->newMainWindow());
0254     QVERIFY(second);
0255 
0256     // close the initial document tab in second window
0257     second->viewManager()->closeView(second->viewManager()->activeView());
0258 
0259     // create a new document, this did crash due to empty view space
0260     second->viewManager()->slotDocumentNew();
0261 }
0262 
0263 void KateViewManagementTests::testTabLRUWithWidgets()
0264 {
0265     app->sessionManager()->sessionNew();
0266     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0267 
0268     // get first main window
0269     KateMainWindow *mw = app->activeKateMainWindow();
0270     auto vm = mw->viewManager();
0271     auto vs = vm->activeViewSpace();
0272 
0273     auto view1 = vm->createView(nullptr);
0274     auto view2 = vm->createView(nullptr);
0275 
0276     QCOMPARE(vs->m_registeredDocuments.size(), 3);
0277     // view2 should be active
0278     QCOMPARE(vm->activeView(), view2);
0279 
0280     // Add a widget
0281     QWidget *widget = new QWidget;
0282     widget->setObjectName(QStringLiteral("widget"));
0283     Utils::addWidget(widget, app->activeMainWindow());
0284     QCOMPARE(vs->currentWidget(), widget);
0285     // There should be no activeView
0286     QVERIFY(!vm->activeView());
0287 
0288     QCOMPARE(vs->m_registeredDocuments.size(), 4);
0289     // activate view1
0290     vm->activateView(view1->document());
0291     QVERIFY(vm->activeView());
0292 
0293     // activate widget again
0294     QCOMPARE(vs->currentWidget(), nullptr);
0295     vm->activateWidget(widget);
0296     QCOMPARE(vs->currentWidget(), widget);
0297     QVERIFY(!vm->activeView());
0298 
0299     // close "widget"
0300     vm->slotDocumentClose();
0301 
0302     // on closing the widget we should fallback to view1
0303     // as it was the last visited view
0304     QCOMPARE(vs->m_registeredDocuments.size(), 3);
0305     QCOMPARE(vm->activeView(), view1);
0306     vm->slotDocumentClose();
0307     // and view2 after closing view1
0308     QCOMPARE(vs->m_registeredDocuments.size(), 2);
0309     QCOMPARE(vm->activeView(), view2);
0310 }
0311 
0312 void KateViewManagementTests::testViewChangedEmittedOnAddWidget()
0313 {
0314     app->sessionManager()->sessionNew();
0315     auto kmw = app->activeMainWindow();
0316     QSignalSpy spy(kmw, &KTextEditor::MainWindow::viewChanged);
0317     Utils::addWidget(new QWidget, kmw);
0318     spy.wait();
0319     QVERIFY(spy.count() == 1);
0320 }
0321 
0322 void KateViewManagementTests::testWidgetAddedEmittedOnAddWidget()
0323 {
0324     app->sessionManager()->sessionNew();
0325     QSignalSpy spy(app->activeMainWindow()->window(), SIGNAL(widgetAdded(QWidget *)));
0326     Utils::addWidget(new QWidget, app->activeMainWindow());
0327     spy.wait();
0328     QVERIFY(spy.count() == 1);
0329 }
0330 
0331 void KateViewManagementTests::testWidgetRemovedEmittedOnRemoveWidget()
0332 {
0333     app->sessionManager()->sessionNew();
0334     auto mw = app->activeMainWindow()->window();
0335     QSignalSpy spy(mw, SIGNAL(widgetRemoved(QWidget *)));
0336     auto w = new QWidget;
0337     Utils::addWidget(w, app->activeMainWindow());
0338     QMetaObject::invokeMethod(mw, "removeWidget", Q_ARG(QWidget *, w));
0339     spy.wait();
0340     QVERIFY(spy.count() == 1);
0341 }
0342 
0343 void KateViewManagementTests::testActivateNotAddedWidget()
0344 {
0345     app->sessionManager()->sessionNew();
0346     auto kmw = app->activeMainWindow();
0347     auto mw = app->activeMainWindow()->window();
0348     QSignalSpy spy(mw, SIGNAL(widgetAdded(QWidget *)));
0349     QSignalSpy spy1(kmw, &KTextEditor::MainWindow::viewChanged);
0350     auto w = new QWidget;
0351     QMetaObject::invokeMethod(mw, "activateWidget", Q_ARG(QWidget *, w));
0352     spy.wait();
0353     spy1.wait();
0354     QVERIFY(spy.count() == 1);
0355     QVERIFY(spy1.count() == 1);
0356 }
0357 
0358 void KateViewManagementTests::testBug460613()
0359 {
0360     // See the bug for details
0361     // This test basically splits into two viewspaces
0362     // Both viewspaces have 1 view
0363     // Adds a new doc to first viewsace and activates
0364     // and then adds the same doc to second viewspace
0365     // without activation
0366     // TEST: closing the doc should only close it
0367     // in the first viewspace, not second as well!
0368     // TEST: closing the doc without view should work
0369 
0370     app->sessionManager()->sessionNew();
0371     KateMainWindow *mw = app->activeKateMainWindow();
0372     auto vm = mw->viewManager();
0373     vm->createView(nullptr);
0374 
0375     vm->slotSplitViewSpaceVert();
0376     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0377 
0378     auto vs1 = *vm->m_viewSpaceList.begin();
0379     auto vs2 = *(vm->m_viewSpaceList.begin() + 1);
0380 
0381     vm->setActiveSpace(vs1);
0382     vs1->createNewDocument();
0383     QCOMPARE(vm->activeView(), vs1->currentView());
0384 
0385     KTextEditor::Document *doc = vm->activeView()->document();
0386     vs2->registerDocument(doc); // registered, but has no view yet
0387 
0388     vm->slotDocumentClose();
0389 
0390     // The doc should still be there in the second viewspace
0391     QVERIFY(vs2->m_registeredDocuments.contains(doc));
0392 
0393     // Try to close the doc in second viewspace
0394     vs2->closeDocument(doc);
0395     QVERIFY(!vs2->hasDocument(doc));
0396 }
0397 
0398 void KateViewManagementTests::testWindowsClosesDocuments()
0399 {
0400     app->sessionManager()->sessionNew();
0401     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0402     QCOMPARE(app->documentManager()->documentList().size(), 1);
0403 
0404     // get first main window
0405     KateMainWindow *first = app->activeKateMainWindow();
0406     QVERIFY(first);
0407 
0408     // create a second one, shall not create a new document
0409     KateMainWindow *second = app->newMainWindow();
0410     QCOMPARE(app->documentManager()->documentList().size(), 1);
0411     QVERIFY(second);
0412 
0413     // second window shall have a new document
0414     second->viewManager()->slotDocumentNew();
0415     QCOMPARE(app->documentManager()->documentList().size(), 2);
0416 
0417     // if we close the second window, the second document shall be gone
0418     delete second;
0419     QCOMPARE(app->documentManager()->documentList().size(), 1);
0420 }
0421 
0422 void KateViewManagementTests::testTabBarHidesShows()
0423 {
0424     app->sessionManager()->sessionNew();
0425     KateMainWindow *mw = app->activeKateMainWindow();
0426     clearAllDocs(mw);
0427     auto vm = mw->viewManager();
0428     auto vs = vm->activeViewSpace();
0429     QTabBar *tabs = vs->m_tabBar;
0430     vs->m_autoHideTabBar = true;
0431     vs->tabBarToggled();
0432 
0433     vm->slotDocumentClose();
0434 
0435     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0436     QCOMPARE(tabs->count(), 1);
0437     QVERIFY(tabs->isHidden()); // only 1 => hide
0438 
0439     app->activeKateMainWindow()->viewManager()->slotDocumentNew();
0440     QCOMPARE(tabs->count(), 2);
0441     QVERIFY(!tabs->isHidden()); // 2 => show
0442 
0443     vm->slotDocumentClose();
0444     QCOMPARE(tabs->count(), 1);
0445     QVERIFY(!vs->m_tabBar->isVisible()); // 1 -> hide
0446 
0447     Utils::addWidget(new QWidget, app->activeMainWindow());
0448     QVERIFY(vs->m_tabBar->isVisible()); // 1 + widget => show
0449 
0450     vm->slotDocumentClose();
0451     QVERIFY(!vs->m_tabBar->isVisible()); // 1 -> hide
0452 
0453     vm->splitViewSpace();
0454     auto *secondVS = vm->activeViewSpace();
0455     QVERIFY(secondVS != vs);
0456 
0457     // if one viewspace has more than 1 tab and its
0458     // tabbar is visible, all other viewspaces shall
0459     // also have visible tabbars
0460 
0461     // make first vs active and create a doc in it
0462     // Expect: both viewspaces have tabbar visible
0463     vm->setActiveSpace(vs);
0464     vm->slotDocumentNew();
0465     QCOMPARE(vs->m_tabBar->count(), 2);
0466     QVERIFY(!vs->m_tabBar->isHidden());
0467     QCOMPARE(secondVS->m_tabBar->count(), 1);
0468     QVERIFY(!secondVS->m_tabBar->isHidden());
0469 
0470     // Expect both have tabbar hidden
0471     vm->slotDocumentClose();
0472     QVERIFY(vs->m_tabBar->isHidden());
0473     QVERIFY(secondVS->m_tabBar->isHidden());
0474 }
0475 
0476 void KateViewManagementTests::testNewWindowHasSameGlobalOptions()
0477 {
0478     /**
0479      * - One mainwindow open with tabbar visible
0480      * - User hides tabbar
0481      * - Then creates a new window
0482      * => TEST: new window should have the tabbar hidden
0483      */
0484     app->sessionManager()->sessionNew();
0485     KateMainWindow *mw = app->activeKateMainWindow();
0486     mw->openUrl(QUrl());
0487     mw->openUrl(QUrl());
0488     QAction *act = mw->action(QStringLiteral("settings_show_tab_bar"));
0489     QVERIFY(act && act->isCheckable());
0490     const bool state = act->isChecked();
0491     qDebug() << "v" << mw->viewManager()->activeViewSpace()->m_tabBar->isVisible() << act->isChecked();
0492     act->setChecked(!state);
0493     QVERIFY(mw->viewManager()->activeViewSpace()->m_tabBar->isVisible() == act->isChecked());
0494     qDebug() << "v" << mw->viewManager()->activeViewSpace()->m_tabBar->isVisible() << act->isChecked();
0495 
0496     // create new window
0497     std::unique_ptr<KateMainWindow> w2(app->newMainWindow(KateApp::self()->sessionManager()->activeSession()->config()));
0498     w2->openUrl(QUrl());
0499     w2->openUrl(QUrl());
0500     QCOMPARE(w2->viewManager()->activeViewSpace()->m_tabBar->isVisible(), mw->viewManager()->activeViewSpace()->m_tabBar->isVisible());
0501 }
0502 
0503 void KateViewManagementTests::testBug465811()
0504 {
0505     app->sessionManager()->sessionNew();
0506     KateMainWindow *mw = app->activeKateMainWindow();
0507     auto vm = mw->viewManager();
0508     auto v1 = vm->createView(nullptr);
0509     auto v2 = vm->createView(nullptr);
0510 
0511     vm->slotSplitViewSpaceVert();
0512     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0513 
0514     auto vs1 = *vm->m_viewSpaceList.begin();
0515     auto vs2 = *(vm->m_viewSpaceList.begin() + 1);
0516 
0517     // on creation there is already a view copied from first viewspace
0518     QCOMPARE(vs1->m_docToView.size(), 2);
0519     QCOMPARE(vs2->m_docToView.size(), 1);
0520     QCOMPARE(vs2->m_docToView.begin()->second->document(), v2->document());
0521 
0522     // Add an unactivated doc to the second viewspace meaning
0523     // there is a doc but no view for it yet
0524     KTextEditor::Document *doc = v1->document();
0525     QVERIFY(doc != v2->document());
0526     vs2->registerDocument(doc);
0527 
0528     // Activate first viewspace
0529     vm->setActiveSpace(vs1);
0530 
0531     // Precondition checks
0532     QCOMPARE(vm->activeViewSpace(), vs1);
0533     QCOMPARE(vs1->m_docToView.size(), 2);
0534     QCOMPARE(vs2->m_docToView.size(), 1); // 1 view
0535     QCOMPARE(vs2->m_registeredDocuments.size(), 2); // 2 docs available
0536 
0537     // Close the active tab of second viewspace(which is inactive)
0538     vs2->closeTabRequest(0);
0539     // The second document's view should be created, instead of it being created in the
0540     // active viewspace
0541     QCOMPARE(vs2->m_docToView.size(), 1);
0542 }
0543 
0544 void KateViewManagementTests::testBug465807()
0545 {
0546     app->sessionManager()->sessionNew();
0547     KateMainWindow *mw = app->activeKateMainWindow();
0548     auto vm = mw->viewManager();
0549     auto v1 = vm->createView(nullptr);
0550     auto v2 = vm->createView(nullptr);
0551 
0552     vm->slotSplitViewSpaceVert();
0553     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0554 
0555     auto vs1 = *vm->m_viewSpaceList.begin();
0556     auto vs2 = *(vm->m_viewSpaceList.begin() + 1);
0557 
0558     // on creation there is already a view copied from first viewspace
0559     QCOMPARE(vs1->m_docToView.size(), 2);
0560     QCOMPARE(vs2->m_docToView.size(), 1);
0561     QCOMPARE(vs2->m_docToView.begin()->second->document(), v2->document());
0562 
0563     vm->setActiveSpace(vs1);
0564     vm->activateView(v1);
0565 
0566     QCOMPARE(vs1->m_tabBar->tabData(0).value<DocOrWidget>().doc(), v1->document());
0567     vs1->closeTabRequest(0);
0568 
0569     QCOMPARE(vm->activeViewSpace(), vs1);
0570     QCOMPARE(vm->activeView(), v2);
0571 }
0572 
0573 void KateViewManagementTests::testBug465808()
0574 {
0575     app->sessionManager()->sessionNew();
0576     KateMainWindow *mw = app->activeKateMainWindow();
0577     auto vm = mw->viewManager();
0578     auto v1 = vm->createView(nullptr);
0579     auto v2 = vm->createView(nullptr);
0580 
0581     vm->slotSplitViewSpaceVert();
0582     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0583 
0584     auto vs1 = *vm->m_viewSpaceList.begin();
0585     auto vs2 = *(vm->m_viewSpaceList.begin() + 1);
0586 
0587     // on creation there is already a view copied from first viewspace
0588     QCOMPARE(vs1->m_docToView.size(), 2);
0589     QCOMPARE(vs2->m_docToView.size(), 1);
0590     QCOMPARE(vs2->m_docToView.begin()->second->document(), v2->document());
0591 
0592     // Switch back to v1
0593     vm->setActiveSpace(vs1);
0594     vm->activateView(v1);
0595 
0596     // Switch to second viewspace and create a view there
0597     vm->setActiveSpace(vs2);
0598     auto v3 = vm->createView();
0599     QCOMPARE(vs2->currentView(), v3);
0600 
0601     // Now vs1 has v1 active and vs2 has v3 active,
0602     // v2 with same doc exists in both viewspaces
0603 
0604     // switch to first viewspace
0605     vm->setActiveSpace(vs1);
0606     QCOMPARE(vs1->currentView(), v1);
0607 
0608     // while vs1 is active, close v3 of vs2
0609     int idx = tabIdxForDoc(vs2->m_tabBar, v3->document());
0610     QVERIFY(idx != -1);
0611     vs2->closeTabRequest(idx);
0612 
0613     // Closing the tab should not change the view in vs1
0614     QCOMPARE(vs1->currentView(), v1);
0615 }
0616 
0617 void KateViewManagementTests::testNewViewCreatedIfViewNotinViewspace()
0618 {
0619     app->sessionManager()->sessionNew();
0620     KateMainWindow *mw = app->activeKateMainWindow();
0621     auto vm = mw->viewManager();
0622     vm->createView(nullptr);
0623 
0624     vm->slotSplitViewSpaceVert();
0625     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0626 
0627     auto vs1 = *vm->m_viewSpaceList.begin();
0628     auto vs2 = *(vm->m_viewSpaceList.begin() + 1);
0629 
0630     QVERIFY(vs2->isActiveSpace());
0631 
0632     auto v2 = vm->createView();
0633     QCOMPARE(vs2->m_docToView.size(), 2);
0634 
0635     v2->insertText(QStringLiteral("Line1\nLine2\nLine3"));
0636     v2->setCursorPosition({2, 2});
0637 
0638     // activate first space
0639     vm->setActiveSpace(vs1);
0640     // Try to activate the doc for which there is no view
0641     // in first space
0642     vm->activateView(v2->document());
0643     // first space should now have 2 views i.e., a view
0644     // should be created for v2->document()
0645     QCOMPARE(vs1->m_docToView.size(), 2);
0646     QCOMPARE(vs1->m_registeredDocuments, vs2->m_registeredDocuments);
0647     // Cursor position is maintained in the new view
0648     QCOMPARE(vs1->m_docToView[v2->document()]->cursorPosition(), v2->cursorPosition());
0649 
0650     v2->document()->clear();
0651     v2->document()->setModified(false);
0652 }
0653 
0654 void KateViewManagementTests::testNewSessionClearsWindowWidgets()
0655 {
0656     // BUG: 466526
0657     app->sessionManager()->sessionNew();
0658     KateMainWindow *mw = app->activeKateMainWindow();
0659     clearAllDocs(mw);
0660 
0661     QPointer<QWidget> w1 = new QWidget;
0662     QPointer<QWidget> w2 = new QWidget;
0663     Utils::addWidget(w1, app->activeMainWindow());
0664     Utils::addWidget(w2, app->activeMainWindow());
0665 
0666     QCOMPARE(mw->viewManager()->activeViewSpace()->m_registeredDocuments.size(), 2);
0667 
0668     app->sessionManager()->sessionNew();
0669 
0670     qApp->processEvents();
0671 
0672     // Widgets are gone now
0673     QCOMPARE(mw->viewManager()->activeViewSpace()->m_registeredDocuments.size(), 1);
0674     QVERIFY(!w1);
0675     QVERIFY(!w2);
0676 }
0677 
0678 void KateViewManagementTests::testViewspaceWithWidgetDoesntCrashOnClose()
0679 {
0680     // two viewspaces, one with widget. Closing the space shouldn't crash us
0681     app->sessionManager()->sessionNew();
0682     KateMainWindow *mw = app->activeKateMainWindow();
0683     clearAllDocs(mw);
0684 
0685     auto vm = mw->viewManager();
0686     vm->createView();
0687     auto vs1 = vm->activeViewSpace();
0688     vm->slotSplitViewSpaceVert();
0689     QVERIFY(vs1 != vm->activeViewSpace());
0690     QCOMPARE(vm->m_viewSpaceList.size(), 2);
0691     QPointer<KateViewSpace> vs2 = vm->activeViewSpace();
0692 
0693     QPointer<QWidget> w1 = new QWidget;
0694     Utils::addWidget(w1, app->activeMainWindow());
0695     QCOMPARE(vs2->currentWidget(), w1);
0696     QVERIFY(vm->activeView() == nullptr);
0697 
0698     QSignalSpy spy(mw, SIGNAL(widgetRemoved(QWidget *)));
0699 
0700     // close the viewspace
0701     vm->slotCloseCurrentViewSpace();
0702 
0703     // The widget and viewspace should be gone
0704     QVERIFY(!vs2);
0705     QVERIFY(!w1);
0706     QVERIFY(spy.count() == 1);
0707 }
0708 
0709 #include "moc_kate_view_mgmt_tests.cpp"