From 40a8d728bb205c912349c67b8901347c9d2be494 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Fri, 26 Jan 2024 22:32:20 +0100 Subject: [PATCH] Update project settings tests --- novelwriter/dialogs/projectsettings.py | 16 +- ...ettings.py => test_dlg_projectsettings.py} | 285 +++++++++--------- 2 files changed, 143 insertions(+), 158 deletions(-) rename tests/test_dialogs/{test_dlg_projsettings.py => test_dlg_projectsettings.py} (50%) diff --git a/novelwriter/dialogs/projectsettings.py b/novelwriter/dialogs/projectsettings.py index b7f50f24..f6ff7730 100644 --- a/novelwriter/dialogs/projectsettings.py +++ b/novelwriter/dialogs/projectsettings.py @@ -90,6 +90,8 @@ class GuiProjectSettings(QDialog): self.buttonBox.rejected.connect(self.close) # Content + SHARED.project.countStatus() + self.settingsPage = _SettingsPage(self) self.statusPage = _StatusPage(self, True) self.importPage = _StatusPage(self, False) @@ -307,12 +309,12 @@ class _StatusPage(NFixedPage): super().__init__(parent=parent) if isStatus: - self.theStatus = SHARED.project.data.itemStatus - pageLabel = self.tr("Novel File Status Levels") + status = SHARED.project.data.itemStatus + pageLabel = self.tr("Novel Document Status Levels") colSetting = "statusColW" else: - self.theStatus = SHARED.project.data.itemImport - pageLabel = self.tr("Note File Importance Levels") + status = SHARED.project.data.itemImport + pageLabel = self.tr("Project Note Importance Levels") colSetting = "importColW" wCol0 = CONFIG.pxInt( @@ -333,14 +335,12 @@ class _StatusPage(NFixedPage): # List Box self.listBox = QTreeWidget(self) - self.listBox.setHeaderLabels([ - self.tr("Label"), self.tr("Usage"), - ]) + self.listBox.setHeaderLabels([self.tr("Label"), self.tr("Usage")]) self.listBox.itemSelectionChanged.connect(self._selectedItem) self.listBox.setColumnWidth(self.COL_LABEL, wCol0) self.listBox.setIndentation(0) - for key, entry in self.theStatus.items(): + for key, entry in status.items(): self._addItem(key, entry["name"], entry["cols"], entry["count"]) # List Controls diff --git a/tests/test_dialogs/test_dlg_projsettings.py b/tests/test_dialogs/test_dlg_projectsettings.py similarity index 50% rename from tests/test_dialogs/test_dlg_projsettings.py rename to tests/test_dialogs/test_dlg_projectsettings.py index 37556245..5b4d5499 100644 --- a/tests/test_dialogs/test_dlg_projsettings.py +++ b/tests/test_dialogs/test_dlg_projectsettings.py @@ -31,7 +31,7 @@ from PyQt5.QtWidgets import QDialog, QAction, QColorDialog from novelwriter import CONFIG, SHARED from novelwriter.enum import nwItemType from novelwriter.dialogs.editlabel import GuiEditLabel -from novelwriter.dialogs.projsettings import GuiProjectSettings +from novelwriter.dialogs.projectsettings import GuiProjectSettings KEY_DELAY = 1 @@ -63,17 +63,17 @@ def testDlgProjSettings_Dialog(qtbot, monkeypatch, nwGUI): qtbot.addWidget(projSettings) # Switch Tabs - projSettings._focusTab(GuiProjectSettings.TAB_REPLACE) - assert projSettings._tabBox.currentWidget() == projSettings.tabReplace + projSettings.sidebar.button(GuiProjectSettings.PAGE_SETTINGS).click() + assert projSettings.mainStack.currentWidget() == projSettings.settingsPage - projSettings._focusTab(GuiProjectSettings.TAB_IMPORT) - assert projSettings._tabBox.currentWidget() == projSettings.tabImport + projSettings.sidebar.button(GuiProjectSettings.PAGE_STATUS).click() + assert projSettings.mainStack.currentWidget() == projSettings.statusPage - projSettings._focusTab(GuiProjectSettings.TAB_STATUS) - assert projSettings._tabBox.currentWidget() == projSettings.tabStatus + projSettings.sidebar.button(GuiProjectSettings.PAGE_IMPORT).click() + assert projSettings.mainStack.currentWidget() == projSettings.importPage - projSettings._focusTab(GuiProjectSettings.TAB_MAIN) - assert projSettings._tabBox.currentWidget() == projSettings.tabMain + projSettings.sidebar.button(GuiProjectSettings.PAGE_REPLACE).click() + assert projSettings.mainStack.currentWidget() == projSettings.replacePage # Clean Up projSettings.close() @@ -83,9 +83,11 @@ def testDlgProjSettings_Dialog(qtbot, monkeypatch, nwGUI): @pytest.mark.gui -def testDlgProjSettings_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): - """Test the main tab of the project settings dialog.""" - monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: [("en", "English [en]")]) +def testDlgProjSettings_SettingsPage(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): + """Test the settings page of the dialog.""" + languages = [("en", "English"), ("de", "German")] + monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda *a: languages) + monkeypatch.setattr(CONFIG, "listLanguages", lambda *a: languages) # Create new project buildTestProject(nwGUI, projPath) @@ -94,72 +96,57 @@ def testDlgProjSettings_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockR # Set some values project = SHARED.project + project.data.setLanguage("en") project.data.setSpellLang("en") project.data.setAuthor("Jane Smith") project.data.setAutoReplace({"A": "B", "C": "D"}) # Create Dialog - projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_MAIN) + projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.PAGE_SETTINGS) projSettings.show() qtbot.addWidget(projSettings) # Settings Tab - # ============ + settings = projSettings.settingsPage - tabMain = projSettings.tabMain + assert settings.projName.text() == "New Project" + assert settings.projAuthor.text() == "Jane Smith" + assert settings.projLang.currentData() == "en" + assert settings.spellLang.currentData() == "en" + assert settings.doBackup.isChecked() is False - assert tabMain.editName.text() == "New Project" - assert tabMain.editTitle.text() == "New Novel" - assert tabMain.editAuthor.text() == "Jane Smith" - assert tabMain.spellLang.currentData() == "en" - assert tabMain.doBackup.isChecked() is False - - tabMain.editName.setText("") - for c in "Project Name": - qtbot.keyClick(tabMain.editName, c, delay=KEY_DELAY) - tabMain.editTitle.setText("") - for c in "Project Title": - qtbot.keyClick(tabMain.editTitle, c, delay=KEY_DELAY) - - tabMain.editAuthor.clear() - for c in "Jane Doe": - qtbot.keyClick(tabMain.editAuthor, c, delay=KEY_DELAY) - - assert tabMain.editName.text() == "Project Name" - assert tabMain.editTitle.text() == "Project Title" - assert tabMain.editAuthor.text() == "Jane Doe" + settings.projName.setText("Project Name") + settings.projAuthor.setText("Jane Doe") + settings.projLang.setCurrentIndex(settings.projLang.findData("de")) + settings.spellLang.setCurrentIndex(settings.spellLang.findData("de")) + settings.doBackup.setChecked(True) projSettings._doSave() assert project.data.name == "Project Name" - assert project.data.title == "Project Title" assert project.data.author == "Jane Doe" + assert project.data.language == "de" + assert project.data.spellLang == "de" + assert project.data.doBackup is False - nwGUI._processProjectSettingsChanges() + nwGUI._processProjectSettingsChanges(False) assert nwGUI.windowTitle() == "novelWriter - Project Name" # qtbot.stop() -# END Test testDlgProjSettings_Main +# END Test testDlgProjSettings_SettingsPage @pytest.mark.gui -def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): - """Test the status and importance tabs of the project settings - dialog. - """ +def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, projPath, mockRnd): + """Test the status and importance pages of the dialog.""" monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True)) - monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: [("en", "English [en]")]) - - # Create new project - mockRnd.reset() buildTestProject(nwGUI, projPath) - CONFIG.setBackupPath(fncPath) # Set some values - theProject = SHARED.project - theProject.tree[C.hTitlePage].setStatus(C.sFinished) # type: ignore - theProject.tree[C.hChapterDoc].setStatus(C.sDraft) # type: ignore - theProject.tree[C.hSceneDoc].setStatus(C.sDraft) # type: ignore + project = SHARED.project + project.tree[C.hTitlePage].setStatus(C.sFinished) # type: ignore + project.tree[C.hChapterDoc].setStatus(C.sDraft) # type: ignore + project.tree[C.hSceneDoc].setStatus(C.sDraft) # type: ignore nwGUI.projView.projTree.setSelectedHandle(C.hPlotRoot) nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) @@ -172,51 +159,54 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPat hCharNote = "0000000000011" hWorldNote = "0000000000012" - theProject.tree[hPlotNote].setImport(C.iMajor) # type: ignore - theProject.tree[hCharNote].setImport(C.iMajor) # type: ignore - theProject.tree[hWorldNote].setImport(C.iMain) # type: ignore + project.tree[hPlotNote].setImport(C.iMajor) # type: ignore + project.tree[hCharNote].setImport(C.iMajor) # type: ignore + project.tree[hWorldNote].setImport(C.iMain) # type: ignore + + nwGUI.rebuildTrees() + project.countStatus() + + assert [e["count"] for _, e in project.data.itemStatus.items()] == [2, 0, 2, 1] + assert [e["count"] for _, e in project.data.itemImport.items()] == [3, 0, 2, 1] # Create Dialog - projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_STATUS) + projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.PAGE_STATUS) projSettings.show() qtbot.addWidget(projSettings) # Status Tab # ========== - tabStatus = projSettings.tabStatus + status = projSettings.statusPage - assert tabStatus.colChanged is False - assert tabStatus.getNewList() == ([], []) - assert tabStatus.listBox.topLevelItemCount() == 4 + assert status.wasChanged is False + assert status.getNewList() == ([], []) + assert status.listBox.topLevelItemCount() == 4 # Can't delete the first item (it's in use) - tabStatus.listBox.clearSelection() - tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(0)) - qtbot.mouseClick(tabStatus.delButton, Qt.LeftButton) - assert tabStatus.listBox.topLevelItemCount() == 4 + status.listBox.clearSelection() + status.listBox.setCurrentItem(status.listBox.topLevelItem(0)) + qtbot.mouseClick(status.delButton, Qt.LeftButton) + assert status.listBox.topLevelItemCount() == 4 # Can delete the second item - tabStatus.listBox.clearSelection() - tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(1)) - qtbot.mouseClick(tabStatus.delButton, Qt.LeftButton) - assert tabStatus.listBox.topLevelItemCount() == 3 + status.listBox.clearSelection() + status.listBox.setCurrentItem(status.listBox.topLevelItem(1)) + qtbot.mouseClick(status.delButton, Qt.LeftButton) + assert status.listBox.topLevelItemCount() == 3 # Add a new item with monkeypatch.context() as mp: mp.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40)) - qtbot.mouseClick(tabStatus.addButton, Qt.LeftButton) - tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(3)) - for _ in range(8): - qtbot.keyClick(tabStatus.editName, Qt.Key_Backspace, delay=KEY_DELAY) - for c in "Final": - qtbot.keyClick(tabStatus.editName, c, delay=KEY_DELAY) - qtbot.mouseClick(tabStatus.colButton, Qt.LeftButton) - qtbot.mouseClick(tabStatus.saveButton, Qt.LeftButton) - assert tabStatus.listBox.topLevelItemCount() == 4 + status.addButton.click() + status.listBox.setCurrentItem(status.listBox.topLevelItem(3)) + status.editName.setText("Final") + status.colButton.click() + status.saveButton.click() + assert status.listBox.topLevelItemCount() == 4 - assert tabStatus.colChanged is True - assert tabStatus.getNewList() == ( + assert status.wasChanged is True + assert status.getNewList() == ( [ { "key": C.sNew, @@ -241,62 +231,62 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPat ) # Move items, none selected -> no change - tabStatus.listBox.clearSelection() - tabStatus._moveItem(1) - assert [x["key"] for x in tabStatus.getNewList()[0]] == [ + status.listBox.clearSelection() + status._moveItem(1) + assert [x["key"] for x in status.getNewList()[0]] == [ C.sNew, C.sDraft, C.sFinished, None ] # Move items, first selected, move up -> no change - tabStatus.listBox.clearSelection() - tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(0)) - tabStatus._moveItem(-1) - assert [x["key"] for x in tabStatus.getNewList()[0]] == [ + status.listBox.clearSelection() + status.listBox.setCurrentItem(status.listBox.topLevelItem(0)) + status._moveItem(-1) + assert [x["key"] for x in status.getNewList()[0]] == [ C.sNew, C.sDraft, C.sFinished, None ] # Move items, last selected, move up -> allowed - tabStatus.listBox.clearSelection() - tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(3)) - tabStatus._moveItem(-1) - assert [x["key"] for x in tabStatus.getNewList()[0]] == [ + status.listBox.clearSelection() + status.listBox.setCurrentItem(status.listBox.topLevelItem(3)) + status._moveItem(-1) + assert [x["key"] for x in status.getNewList()[0]] == [ C.sNew, C.sDraft, None, C.sFinished ] # Move items, same selected, move down -> allowed - tabStatus._moveItem(1) - assert [x["key"] for x in tabStatus.getNewList()[0]] == [ + status._moveItem(1) + assert [x["key"] for x in status.getNewList()[0]] == [ C.sNew, C.sDraft, C.sFinished, None ] # Importance Tab # ============== - tabImport = projSettings.tabImport - projSettings._focusTab(GuiProjectSettings.TAB_IMPORT) + importance = projSettings.importPage + projSettings._sidebarClicked(GuiProjectSettings.PAGE_IMPORT) # Delete unused entry - tabImport.listBox.clearSelection() - tabImport.listBox.setCurrentItem(tabImport.listBox.topLevelItem(1)) - qtbot.mouseClick(tabImport.delButton, Qt.LeftButton) - assert tabImport.listBox.topLevelItemCount() == 3 + importance.listBox.clearSelection() + importance.listBox.setCurrentItem(importance.listBox.topLevelItem(1)) + qtbot.mouseClick(importance.delButton, Qt.LeftButton) + assert importance.listBox.topLevelItemCount() == 3 # Add a new entry with monkeypatch.context() as mp: mp.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40)) - qtbot.mouseClick(tabImport.addButton, Qt.LeftButton) - tabImport.listBox.clearSelection() - tabImport.listBox.setCurrentItem(tabImport.listBox.topLevelItem(3)) + qtbot.mouseClick(importance.addButton, Qt.LeftButton) + importance.listBox.clearSelection() + importance.listBox.setCurrentItem(importance.listBox.topLevelItem(3)) for _ in range(8): - qtbot.keyClick(tabImport.editName, Qt.Key_Backspace, delay=KEY_DELAY) + qtbot.keyClick(importance.editName, Qt.Key_Backspace, delay=KEY_DELAY) for c in "Final": - qtbot.keyClick(tabImport.editName, c, delay=KEY_DELAY) - qtbot.mouseClick(tabImport.colButton, Qt.LeftButton) - qtbot.mouseClick(tabImport.saveButton, Qt.LeftButton) - assert tabImport.listBox.topLevelItemCount() == 4 + qtbot.keyClick(importance.editName, c, delay=KEY_DELAY) + qtbot.mouseClick(importance.colButton, Qt.LeftButton) + qtbot.mouseClick(importance.saveButton, Qt.LeftButton) + assert importance.listBox.topLevelItemCount() == 4 - assert tabImport.colChanged is True - assert tabImport.getNewList() == ( + assert importance.wasChanged is True + assert importance.getNewList() == ( [ { "key": C.iNew, @@ -323,13 +313,13 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPat # Check Project projSettings._doSave() - statusItems = dict(theProject.data.itemStatus.items()) + statusItems = dict(project.data.itemStatus.items()) assert statusItems[C.sNew]["name"] == "New" assert statusItems[C.sDraft]["name"] == "Draft" assert statusItems[C.sFinished]["name"] == "Finished" assert statusItems["s000013"]["name"] == "Final" - importItems = dict(theProject.data.itemImport.items()) + importItems = dict(project.data.itemImport.items()) assert importItems[C.iNew]["name"] == "New" assert importItems[C.iMajor]["name"] == "Major" assert importItems[C.iMain]["name"] == "Main" @@ -341,83 +331,78 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPat @pytest.mark.gui -def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): - """Test the auto-replace tab of the project settings dialog.""" +def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, projPath, mockRnd): + """Test the auto-replace page of the dialog.""" monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True)) - monkeypatch.setattr(SHARED._spelling, "listDictionaries", lambda: [("en", "English [en]")]) - - # Create new project - mockRnd.reset() buildTestProject(nwGUI, projPath) - CONFIG.setBackupPath(fncPath) # Set some values - theProject = SHARED.project - theProject.data.setAutoReplace({ + project = SHARED.project + project.data.setAutoReplace({ "A": "B", "C": "D" }) # Create Dialog - projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_REPLACE) + projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.PAGE_REPLACE) projSettings.show() qtbot.addWidget(projSettings) # Auto-Replace Tab # ================ - tabReplace = projSettings.tabReplace + replace = projSettings.replacePage - assert tabReplace.listBox.topLevelItem(0).text(0) == "" # type: ignore - assert tabReplace.listBox.topLevelItem(0).text(1) == "B" # type: ignore - assert tabReplace.listBox.topLevelItem(1).text(0) == "" # type: ignore - assert tabReplace.listBox.topLevelItem(1).text(1) == "D" # type: ignore - assert tabReplace.listBox.topLevelItemCount() == 2 + assert replace.listBox.topLevelItem(0).text(0) == "" # type: ignore + assert replace.listBox.topLevelItem(0).text(1) == "B" # type: ignore + assert replace.listBox.topLevelItem(1).text(0) == "" # type: ignore + assert replace.listBox.topLevelItem(1).text(1) == "D" # type: ignore + assert replace.listBox.topLevelItemCount() == 2 # Nothing to save or delete - tabReplace.listBox.clearSelection() - tabReplace._saveEntry() - tabReplace._delEntry() - assert tabReplace.listBox.topLevelItemCount() == 2 + replace.listBox.clearSelection() + replace._saveEntry() + replace._delEntry() + assert replace.listBox.topLevelItemCount() == 2 # Create a new entry - qtbot.mouseClick(tabReplace.addButton, Qt.LeftButton) - assert tabReplace.listBox.topLevelItemCount() == 3 - assert tabReplace.listBox.topLevelItem(2).text(0) == "" # type: ignore - assert tabReplace.listBox.topLevelItem(2).text(1) == "" # type: ignore + qtbot.mouseClick(replace.addButton, Qt.LeftButton) + assert replace.listBox.topLevelItemCount() == 3 + assert replace.listBox.topLevelItem(2).text(0) == "" # type: ignore + assert replace.listBox.topLevelItem(2).text(1) == "" # type: ignore # Edit the entry - tabReplace.listBox.setCurrentItem(tabReplace.listBox.topLevelItem(2)) - tabReplace.editKey.setText("") + replace.listBox.setCurrentItem(replace.listBox.topLevelItem(2)) + replace.editKey.setText("") for c in "Th is ": - qtbot.keyClick(tabReplace.editKey, c, delay=KEY_DELAY) - tabReplace.editValue.setText("") + qtbot.keyClick(replace.editKey, c, delay=KEY_DELAY) + replace.editValue.setText("") for c in "With This Stuff ": - qtbot.keyClick(tabReplace.editValue, c, delay=KEY_DELAY) - qtbot.mouseClick(tabReplace.saveButton, Qt.LeftButton) - assert tabReplace.listBox.topLevelItem(2).text(0) == "" # type: ignore - assert tabReplace.listBox.topLevelItem(2).text(1) == "With This Stuff " # type: ignore + qtbot.keyClick(replace.editValue, c, delay=KEY_DELAY) + qtbot.mouseClick(replace.saveButton, Qt.LeftButton) + assert replace.listBox.topLevelItem(2).text(0) == "" # type: ignore + assert replace.listBox.topLevelItem(2).text(1) == "With This Stuff " # type: ignore # Create a new entry again - tabReplace.listBox.clearSelection() - qtbot.mouseClick(tabReplace.addButton, Qt.LeftButton) - assert tabReplace.listBox.topLevelItemCount() == 4 + replace.listBox.clearSelection() + qtbot.mouseClick(replace.addButton, Qt.LeftButton) + assert replace.listBox.topLevelItemCount() == 4 # The list is sorted, so we must find it newIdx = -1 - for i in range(tabReplace.listBox.topLevelItemCount()): - if tabReplace.listBox.topLevelItem(i).text(0) == "": # type: ignore + for i in range(replace.listBox.topLevelItemCount()): + if replace.listBox.topLevelItem(i).text(0) == "": # type: ignore newIdx = i break assert newIdx >= 0 # Then delete the new item - tabReplace.listBox.setCurrentItem(tabReplace.listBox.topLevelItem(newIdx)) - qtbot.mouseClick(tabReplace.delButton, Qt.LeftButton) - assert tabReplace.listBox.topLevelItemCount() == 3 + replace.listBox.setCurrentItem(replace.listBox.topLevelItem(newIdx)) + qtbot.mouseClick(replace.delButton, Qt.LeftButton) + assert replace.listBox.topLevelItemCount() == 3 # Check Project projSettings._doSave() - assert theProject.data.autoReplace == { + assert project.data.autoReplace == { "A": "B", "C": "D", "This": "With This Stuff" }