Refactor project settings test

This commit is contained in:
Veronica Berglyd Olsen
2022-10-25 15:48:29 +02:00
parent 2ee6adcf35
commit 7b04d57605
4 changed files with 351 additions and 243 deletions
+6 -2
View File
@@ -88,7 +88,7 @@ class GuiProjectSettings(PagedDialog):
self.addControls(self.buttonBox) self.addControls(self.buttonBox)
# Flags # Flags
self.spellChanged = False self._spellChanged = False
# Focus Tab # Focus Tab
self._focusTab(focusTab) self._focusTab(focusTab)
@@ -97,6 +97,10 @@ class GuiProjectSettings(PagedDialog):
return return
@property
def spellChanged(self):
return self._spellChanged
## ##
# Slots # Slots
## ##
@@ -116,7 +120,7 @@ class GuiProjectSettings(PagedDialog):
self.theProject.setProjBackup(doBackup) self.theProject.setProjBackup(doBackup)
# Remember this as updating spell dictionary can be expensive # Remember this as updating spell dictionary can be expensive
self.spellChanged = self.theProject.setSpellLang(spellLang) self._spellChanged = self.theProject.setSpellLang(spellLang)
if self.tabStatus.colChanged: if self.tabStatus.colChanged:
newList, delList = self.tabStatus.getNewList() newList, delList = self.tabStatus.getNewList()
@@ -1,83 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-10-20 18:21:59">
<project>
<name>Project Name</name>
<title>Project Title</title>
<author>Jane Doe</author>
<author>John Doh</author>
<saveCount>1</saveCount>
<autoCount>1</autoCount>
<editTime>0</editTime>
</project>
<settings>
<doBackup>True</doBackup>
<language>None</language>
<spellCheck>False</spellCheck>
<spellLang>en</spellLang>
<lastEdited>None</lastEdited>
<lastViewed>None</lastViewed>
<lastNovel>None</lastNovel>
<lastOutline>None</lastOutline>
<lastWordCount>9</lastWordCount>
<novelWordCount>9</novelWordCount>
<notesWordCount>0</notesWordCount>
<autoReplace>
<entry key="A">B</entry>
<entry key="C">D</entry>
<entry key="This">With This Stuff</entry>
</autoReplace>
<titleFormat>
<title>%title%</title>
<chapter>%title%</chapter>
<unnumbered>%title%</unnumbered>
<scene>* * *</scene>
<section></section>
</titleFormat>
<status>
<entry key="s000000" count="5" red="100" green="100" blue="100">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0">Note</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0">Finished</entry>
<entry key="s000010" count="0" red="20" green="30" blue="40">Final</entry>
</status>
<importance>
<entry key="i000004" count="3" red="100" green="100" blue="100">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0">Major</entry>
<entry key="i000011" count="0" red="100" green="100" blue="100">Final</entry>
</importance>
</settings>
<content count="8">
<item handle="0000000000008" parent="None" root="0000000000008" order="0" type="ROOT" class="NOVEL">
<meta expanded="False"/>
<name status="s000000" import="i000004">Novel</name>
</item>
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" mainHeading="H1" charCount="20" wordCount="5" paraCount="1" cursorPos="0"/>
<name status="s000000" import="i000004" active="True">Title Page</name>
</item>
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="1" type="FOLDER" class="NOVEL">
<meta expanded="False"/>
<name status="s000000" import="i000004">New Chapter</name>
</item>
<item handle="000000000000e" parent="000000000000d" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" mainHeading="H2" charCount="11" wordCount="2" paraCount="0" cursorPos="0"/>
<name status="s000000" import="i000004" active="True">New Chapter</name>
</item>
<item handle="000000000000f" parent="000000000000d" root="0000000000008" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" mainHeading="H3" charCount="9" wordCount="2" paraCount="0" cursorPos="0"/>
<name status="s000000" import="i000004" active="True">New Scene</name>
</item>
<item handle="0000000000009" parent="None" root="0000000000009" order="1" type="ROOT" class="PLOT">
<meta expanded="False"/>
<name status="s000000" import="i000004">Plot</name>
</item>
<item handle="000000000000a" parent="None" root="000000000000a" order="2" type="ROOT" class="CHARACTER">
<meta expanded="False"/>
<name status="s000000" import="i000004">Characters</name>
</item>
<item handle="000000000000b" parent="None" root="000000000000b" order="3" type="ROOT" class="WORLD">
<meta expanded="False"/>
<name status="s000000" import="i000004">World</name>
</item>
</content>
</novelWriterXML>
+334 -158
View File
@@ -19,56 +19,46 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import os
import pytest import pytest
from shutil import copyfile from novelwriter.enum import nwItemType
from tools import cmpFiles, getGuiItem, buildTestProject from tools import C, getGuiItem, buildTestProject
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog, QAction, QMessageBox, QColorDialog from PyQt5.QtWidgets import QDialog, QAction, QMessageBox, QColorDialog
from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.dialogs.projsettings import GuiProjectSettings from novelwriter.dialogs.projsettings import GuiProjectSettings
keyDelay = 2 keyDelay = 2
typeDelay = 1 typeDelay = 1
stepDelay = 20 stepDelay = 20
statusKeys = ["s000000", "s000001", "s000002", "s000003"]
importKeys = ["i000004", "i000005", "i000006", "i000007"]
@pytest.mark.gui @pytest.mark.gui
def testDlgProjSettings_Dialog( def testDlgProjSettings_Dialog(qtbot, monkeypatch, nwGUI):
qtbot, monkeypatch, nwGUI, fncDir, fncProj, outDir, refDir, mockRnd """Test the main dialog class. Saving settings is not tested in this
): test, but are instead tested in the individual tab tests.
"""Test the full project settings dialog.
""" """
projFile = os.path.join(fncProj, "nwProject.nwx")
testFile = os.path.join(outDir, "guiProjSettings_Dialog_nwProject.nwx")
compFile = os.path.join(refDir, "guiProjSettings_Dialog_nwProject.nwx")
# Block message box # Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
# Block the GUI blocking thread
monkeypatch.setattr(GuiProjectSettings, "exec_", lambda *a: None)
monkeypatch.setattr(GuiProjectSettings, "result", lambda *a: QDialog.Accepted)
monkeypatch.setattr(GuiProjectSettings, "spellChanged", lambda *a: True)
# Check that we cannot open when there is no project # Check that we cannot open when there is no project
nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger)
assert getGuiItem("GuiProjectSettings") is None assert getGuiItem("GuiProjectSettings") is None
# Create new project # Pretend we have a project
buildTestProject(nwGUI, fncProj) nwGUI.hasProject = True
nwGUI.mainConf.backupPath = fncDir
nwGUI.theProject.setSpellLang("en") nwGUI.theProject.setSpellLang("en")
nwGUI.theProject.setBookAuthors("Jane Smith\nJohn Smith")
nwGUI.theProject.setAutoReplace({"A": "B", "C": "D"})
# Get the dialog object # Get the dialog object
monkeypatch.setattr(GuiProjectSettings, "exec_", lambda *a: None)
monkeypatch.setattr(GuiProjectSettings, "result", lambda *a: QDialog.Accepted)
monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries", lambda: [("en", "none")])
nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiProjectSettings") is not None, timeout=1000) qtbot.waitUntil(lambda: getGuiItem("GuiProjectSettings") is not None, timeout=1000)
@@ -77,83 +67,189 @@ def testDlgProjSettings_Dialog(
projEdit.show() projEdit.show()
qtbot.addWidget(projEdit) qtbot.addWidget(projEdit)
# Switch Tabs
projEdit._focusTab(GuiProjectSettings.TAB_REPLACE)
assert projEdit._tabBox.currentWidget() == projEdit.tabReplace
projEdit._focusTab(GuiProjectSettings.TAB_IMPORT)
assert projEdit._tabBox.currentWidget() == projEdit.tabImport
projEdit._focusTab(GuiProjectSettings.TAB_STATUS)
assert projEdit._tabBox.currentWidget() == projEdit.tabStatus
projEdit._focusTab(GuiProjectSettings.TAB_MAIN)
assert projEdit._tabBox.currentWidget() == projEdit.tabMain
# Clean Up
projEdit._doClose()
# qtbot.stop()
# END Test testDlgProjSettings_Dialog
@pytest.mark.gui
def testDlgProjSettings_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
"""Test the main tab of the project settings dialog.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
# Mock components
monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries", lambda: [("en", "none")])
# Create new project
buildTestProject(nwGUI, fncProj)
mockRnd.reset()
nwGUI.mainConf.backupPath = fncDir
# Set some values
theProject = nwGUI.theProject
theProject.setSpellLang("en")
theProject.setBookAuthors("Jane Smith\nJohn Smith")
theProject.setAutoReplace({"A": "B", "C": "D"})
# Create Dialog
projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_MAIN)
projSettings.show()
qtbot.addWidget(projSettings)
# Settings Tab # Settings Tab
# ============ # ============
assert projEdit.tabMain.editName.text() == "New Project" tabMain = projSettings.tabMain
assert projEdit.tabMain.editTitle.text() == "New Novel"
assert projEdit.tabMain.editAuthors.toPlainText() == "Jane Smith\nJohn Smith" assert tabMain.editName.text() == "New Project"
assert projEdit.tabMain.spellLang.currentData() == "en" assert tabMain.editTitle.text() == "New Novel"
assert projEdit.tabMain.doBackup.isChecked() is False assert tabMain.editAuthors.toPlainText() == "Jane Smith\nJohn Smith"
assert tabMain.spellLang.currentData() == "en"
assert tabMain.doBackup.isChecked() is False
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
projEdit.tabMain.editName.setText("") tabMain.editName.setText("")
for c in "Project Name": for c in "Project Name":
qtbot.keyClick(projEdit.tabMain.editName, c, delay=typeDelay) qtbot.keyClick(tabMain.editName, c, delay=typeDelay)
projEdit.tabMain.editTitle.setText("") tabMain.editTitle.setText("")
for c in "Project Title": for c in "Project Title":
qtbot.keyClick(projEdit.tabMain.editTitle, c, delay=typeDelay) qtbot.keyClick(tabMain.editTitle, c, delay=typeDelay)
projEdit.tabMain.editAuthors.clear() tabMain.editAuthors.clear()
for c in "Jane Doe": for c in "Jane Doe":
qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=typeDelay) qtbot.keyClick(tabMain.editAuthors, c, delay=typeDelay)
qtbot.keyClick(projEdit.tabMain.editAuthors, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(tabMain.editAuthors, Qt.Key_Return, delay=keyDelay)
for c in "John Doh": for c in "John Doh":
qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=typeDelay) qtbot.keyClick(tabMain.editAuthors, c, delay=typeDelay)
qtbot.keyClick(projEdit.tabMain.editAuthors, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(tabMain.editAuthors, Qt.Key_Return, delay=keyDelay)
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
assert projEdit.tabMain.editName.text() == "Project Name" assert tabMain.editName.text() == "Project Name"
assert projEdit.tabMain.editTitle.text() == "Project Title" assert tabMain.editTitle.text() == "Project Title"
assert projEdit.tabMain.editAuthors.toPlainText() == "Jane Doe\nJohn Doh\n" assert tabMain.editAuthors.toPlainText() == "Jane Doe\nJohn Doh\n"
assert projSettings.spellChanged is False
projSettings._doSave()
assert theProject.projName == "Project Name"
assert theProject.bookTitle == "Project Title"
assert theProject.bookAuthors == ["Jane Doe", "John Doh"]
# Clean up
projSettings._doClose()
# qtbot.stop()
# END Test testDlgProjSettings_Main
@pytest.mark.gui
def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
"""Test the status and importance tabs of the project settings
dialog.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
# Mock components
monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries", lambda: [("en", "none")])
# Create new project
mockRnd.reset()
buildTestProject(nwGUI, fncProj)
nwGUI.mainConf.backupPath = fncDir
# Set some values
theProject = nwGUI.theProject
theProject.tree[C.hTitlePage].setStatus(C.sFinished)
theProject.tree[C.hChapterDoc].setStatus(C.sDraft)
theProject.tree[C.hSceneDoc].setStatus(C.sDraft)
nwGUI.projView.projTree.setSelectedHandle(C.hPlotRoot)
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True)
nwGUI.projView.projTree.setSelectedHandle(C.hCharRoot)
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True)
nwGUI.projView.projTree.setSelectedHandle(C.hWorldRoot)
nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True)
hPlotNote = "0000000000010"
hCharNote = "0000000000011"
hWorldNote = "0000000000012"
theProject.tree[hPlotNote].setImport(C.iMajor)
theProject.tree[hCharNote].setImport(C.iMajor)
theProject.tree[hWorldNote].setImport(C.iMain)
# Create Dialog
projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_STATUS)
projSettings.show()
qtbot.addWidget(projSettings)
# Status Tab # Status Tab
# ========== # ==========
projEdit._tabBox.setCurrentWidget(projEdit.tabStatus) tabStatus = projSettings.tabStatus
assert projEdit.tabStatus.colChanged is False assert tabStatus.colChanged is False
assert projEdit.tabStatus.getNewList() == ([], []) assert tabStatus.getNewList() == ([], [])
assert projEdit.tabStatus.listBox.topLevelItemCount() == 4 assert tabStatus.listBox.topLevelItemCount() == 4
# Can't delete the first item (it's in use) # Can't delete the first item (it's in use)
projEdit.tabStatus.listBox.clearSelection() tabStatus.listBox.clearSelection()
projEdit.tabStatus.listBox.topLevelItem(0).setSelected(True) tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(0))
qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton) qtbot.mouseClick(tabStatus.delButton, Qt.LeftButton)
assert projEdit.tabStatus.listBox.topLevelItemCount() == 4 assert tabStatus.listBox.topLevelItemCount() == 4
# Can delete the third item # Can delete the second item
projEdit.tabStatus.listBox.clearSelection() tabStatus.listBox.clearSelection()
projEdit.tabStatus.listBox.topLevelItem(2).setSelected(True) tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(1))
qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton) qtbot.mouseClick(tabStatus.delButton, Qt.LeftButton)
assert projEdit.tabStatus.listBox.topLevelItemCount() == 3 assert tabStatus.listBox.topLevelItemCount() == 3
# Add a new item # Add a new item
monkeypatch.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40)) with monkeypatch.context() as mp:
qtbot.mouseClick(projEdit.tabStatus.addButton, Qt.LeftButton) mp.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40))
projEdit.tabStatus.listBox.topLevelItem(3).setSelected(True) qtbot.mouseClick(tabStatus.addButton, Qt.LeftButton)
for n in range(8): tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(3))
qtbot.keyClick(projEdit.tabStatus.editName, Qt.Key_Backspace, delay=typeDelay) for _ in range(8):
for c in "Final": qtbot.keyClick(tabStatus.editName, Qt.Key_Backspace, delay=typeDelay)
qtbot.keyClick(projEdit.tabStatus.editName, c, delay=typeDelay) for c in "Final":
qtbot.mouseClick(projEdit.tabStatus.colButton, Qt.LeftButton) qtbot.keyClick(tabStatus.editName, c, delay=typeDelay)
qtbot.mouseClick(projEdit.tabStatus.saveButton, Qt.LeftButton) qtbot.mouseClick(tabStatus.colButton, Qt.LeftButton)
assert projEdit.tabStatus.listBox.topLevelItemCount() == 4 qtbot.mouseClick(tabStatus.saveButton, Qt.LeftButton)
qtbot.wait(stepDelay) assert tabStatus.listBox.topLevelItemCount() == 4
assert projEdit.tabStatus.colChanged is True assert tabStatus.colChanged is True
assert projEdit.tabStatus.getNewList() == ( assert tabStatus.getNewList() == (
[ [
{ {
"key": statusKeys[0], "key": C.sNew,
"name": "New", "name": "New",
"cols": (100, 100, 100) "cols": (100, 100, 100)
}, { }, {
"key": statusKeys[1], "key": C.sDraft,
"name": "Note", "name": "Draft",
"cols": (200, 50, 0) "cols": (200, 150, 0)
}, { }, {
"key": statusKeys[3], "key": C.sFinished,
"name": "Finished", "name": "Finished",
"cols": (50, 200, 0) "cols": (50, 200, 0)
}, { }, {
@@ -162,121 +258,201 @@ def testDlgProjSettings_Dialog(
"cols": (20, 30, 40) "cols": (20, 30, 40)
} }
], [ ], [
statusKeys[2] # Deleted item C.sNote # Deleted item
] ]
) )
# Move items # Move items, none selected -> no change
projEdit.tabStatus.listBox.clearSelection() tabStatus.listBox.clearSelection()
projEdit.tabStatus._moveItem(1) tabStatus._moveItem(1)
assert [x["key"] for x in projEdit.tabStatus.getNewList()[0]] == [ assert [x["key"] for x in tabStatus.getNewList()[0]] == [
statusKeys[0], statusKeys[1], statusKeys[3], None C.sNew, C.sDraft, C.sFinished, None
] ]
projEdit.tabStatus.listBox.clearSelection() # Move items, first selected, move up -> no change
projEdit.tabStatus.listBox.topLevelItem(0).setSelected(True) tabStatus.listBox.clearSelection()
projEdit.tabStatus._moveItem(-1) tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(0))
assert [x["key"] for x in projEdit.tabStatus.getNewList()[0]] == [ tabStatus._moveItem(-1)
statusKeys[0], statusKeys[1], statusKeys[3], None assert [x["key"] for x in tabStatus.getNewList()[0]] == [
C.sNew, C.sDraft, C.sFinished, None
] ]
projEdit.tabStatus.listBox.clearSelection() # Move items, last selected, move up -> allowed
projEdit.tabStatus.listBox.topLevelItem(3).setSelected(True) tabStatus.listBox.clearSelection()
projEdit.tabStatus._moveItem(-1) tabStatus.listBox.setCurrentItem(tabStatus.listBox.topLevelItem(3))
assert [x["key"] for x in projEdit.tabStatus.getNewList()[0]] == [ tabStatus._moveItem(-1)
statusKeys[0], statusKeys[1], None, statusKeys[3] assert [x["key"] for x in tabStatus.getNewList()[0]] == [
C.sNew, C.sDraft, None, C.sFinished
] ]
projEdit.tabStatus._moveItem(1)
assert [x["key"] for x in projEdit.tabStatus.getNewList()[0]] == [ # Move items, same selected, move down -> allowed
statusKeys[0], statusKeys[1], statusKeys[3], None tabStatus._moveItem(1)
assert [x["key"] for x in tabStatus.getNewList()[0]] == [
C.sNew, C.sDraft, C.sFinished, None
] ]
# Importance Tab # Importance Tab
# ============== # ==============
projEdit._tabBox.setCurrentWidget(projEdit.tabImport) tabImport = projSettings.tabImport
projEdit.tabStatus.listBox.clearSelection() projSettings._focusTab(GuiProjectSettings.TAB_IMPORT)
projEdit.tabImport.listBox.topLevelItem(3).setSelected(True)
qtbot.mouseClick(projEdit.tabImport.delButton, Qt.LeftButton) # Delete unused entry
qtbot.mouseClick(projEdit.tabImport.addButton, Qt.LeftButton) tabImport.listBox.clearSelection()
projEdit.tabStatus.listBox.clearSelection() tabImport.listBox.setCurrentItem(tabImport.listBox.topLevelItem(1))
projEdit.tabImport.listBox.topLevelItem(3).setSelected(True) qtbot.mouseClick(tabImport.delButton, Qt.LeftButton)
for n in range(8): assert tabImport.listBox.topLevelItemCount() == 3
qtbot.keyClick(projEdit.tabImport.editName, Qt.Key_Backspace, delay=typeDelay)
for c in "Final": # Add a new entry
qtbot.keyClick(projEdit.tabImport.editName, c, delay=typeDelay) with monkeypatch.context() as mp:
qtbot.mouseClick(projEdit.tabImport.saveButton, Qt.LeftButton) mp.setattr(QColorDialog, "getColor", lambda *a: QColor(20, 30, 40))
qtbot.wait(stepDelay) qtbot.mouseClick(tabImport.addButton, Qt.LeftButton)
tabImport.listBox.clearSelection()
tabImport.listBox.setCurrentItem(tabImport.listBox.topLevelItem(3))
for _ in range(8):
qtbot.keyClick(tabImport.editName, Qt.Key_Backspace, delay=typeDelay)
for c in "Final":
qtbot.keyClick(tabImport.editName, c, delay=typeDelay)
qtbot.mouseClick(tabImport.colButton, Qt.LeftButton)
qtbot.mouseClick(tabImport.saveButton, Qt.LeftButton)
assert tabImport.listBox.topLevelItemCount() == 4
assert tabImport.colChanged is True
assert tabImport.getNewList() == (
[
{
"key": C.iNew,
"name": "New",
"cols": (100, 100, 100)
}, {
"key": C.iMajor,
"name": "Major",
"cols": (200, 150, 0)
}, {
"key": C.iMain,
"name": "Main",
"cols": (50, 200, 0)
}, {
"key": None,
"name": "Final",
"cols": (20, 30, 40)
}
], [
C.iMinor # Deleted item
]
)
# Check Project
projSettings._doSave()
statusItems = dict(theProject.statusItems.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.importItems.items())
assert importItems[C.iNew]["name"] == "New"
assert importItems[C.iMajor]["name"] == "Major"
assert importItems[C.iMain]["name"] == "Main"
assert importItems["i000014"]["name"] == "Final"
# Clean up
# qtbot.stop()
projSettings._doClose()
# END Test testDlgProjSettings_StatusImport
@pytest.mark.gui
def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
"""Test the auto-replace tab of the project settings dialog.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
# Mock components
monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries", lambda: [("en", "none")])
# Create new project
mockRnd.reset()
buildTestProject(nwGUI, fncProj)
nwGUI.mainConf.backupPath = fncDir
# Set some values
theProject = nwGUI.theProject
theProject.autoReplace = {
"A": "B", "C": "D"
}
# Create Dialog
projSettings = GuiProjectSettings(nwGUI, GuiProjectSettings.TAB_REPLACE)
projSettings.show()
qtbot.addWidget(projSettings)
# Auto-Replace Tab # Auto-Replace Tab
# ================ # ================
qtbot.wait(stepDelay) tabReplace = projSettings.tabReplace
projEdit._tabBox.setCurrentWidget(projEdit.tabReplace)
assert projEdit.tabReplace.listBox.topLevelItem(0).text(0) == "<A>" assert tabReplace.listBox.topLevelItem(0).text(0) == "<A>"
assert projEdit.tabReplace.listBox.topLevelItem(0).text(1) == "B" assert tabReplace.listBox.topLevelItem(0).text(1) == "B"
assert projEdit.tabReplace.listBox.topLevelItem(1).text(0) == "<C>" assert tabReplace.listBox.topLevelItem(1).text(0) == "<C>"
assert projEdit.tabReplace.listBox.topLevelItem(1).text(1) == "D" assert tabReplace.listBox.topLevelItem(1).text(1) == "D"
assert tabReplace.listBox.topLevelItemCount() == 2
qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton) # Nothing to save or delete
projEdit.tabReplace.listBox.topLevelItem(2).setSelected(True) tabReplace.listBox.clearSelection()
projEdit.tabReplace.editKey.setText("") assert tabReplace._saveEntry() is False
assert tabReplace._delEntry() is False
assert tabReplace.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) == "<keyword3>"
assert tabReplace.listBox.topLevelItem(2).text(1) == ""
# Edit the entry
tabReplace.listBox.setCurrentItem(tabReplace.listBox.topLevelItem(2))
tabReplace.editKey.setText("")
for c in "Th is ": for c in "Th is ":
qtbot.keyClick(projEdit.tabReplace.editKey, c, delay=typeDelay) qtbot.keyClick(tabReplace.editKey, c, delay=typeDelay)
projEdit.tabReplace.editValue.setText("") tabReplace.editValue.setText("")
for c in "With This Stuff ": for c in "With This Stuff ":
qtbot.keyClick(projEdit.tabReplace.editValue, c, delay=typeDelay) qtbot.keyClick(tabReplace.editValue, c, delay=typeDelay)
qtbot.mouseClick(projEdit.tabReplace.saveButton, Qt.LeftButton) qtbot.mouseClick(tabReplace.saveButton, Qt.LeftButton)
assert tabReplace.listBox.topLevelItem(2).text(0) == "<This>"
assert tabReplace.listBox.topLevelItem(2).text(1) == "With This Stuff "
qtbot.wait(stepDelay) # Create a new entry again
projEdit.tabReplace.listBox.clearSelection() tabReplace.listBox.clearSelection()
assert not projEdit.tabReplace._saveEntry() qtbot.mouseClick(tabReplace.addButton, Qt.LeftButton)
assert not projEdit.tabReplace._delEntry() assert tabReplace.listBox.topLevelItemCount() == 4
qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton)
# The list is sorted, so we must find it
newIdx = -1 newIdx = -1
for i in range(projEdit.tabReplace.listBox.topLevelItemCount()): for i in range(tabReplace.listBox.topLevelItemCount()):
if projEdit.tabReplace.listBox.topLevelItem(i).text(0) == "<keyword4>": if tabReplace.listBox.topLevelItem(i).text(0) == "<keyword4>":
newIdx = i newIdx = i
break break
assert newIdx >= 0 assert newIdx >= 0
newItem = projEdit.tabReplace.listBox.topLevelItem(newIdx)
projEdit.tabReplace.listBox.setCurrentItem(newItem)
qtbot.mouseClick(projEdit.tabReplace.delButton, Qt.LeftButton)
qtbot.wait(stepDelay)
# Save & Check # Then delete the new item
# ============ tabReplace.listBox.setCurrentItem(tabReplace.listBox.topLevelItem(newIdx))
qtbot.mouseClick(tabReplace.delButton, Qt.LeftButton)
assert tabReplace.listBox.topLevelItemCount() == 3
projEdit._doSave() # Check Project
projSettings._doSave()
assert theProject.autoReplace == {
"A": "B", "C": "D", "This": "With This Stuff"
}
# Open again, and check project settings # Clean up
nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) # qtbot.stop()
qtbot.waitUntil(lambda: getGuiItem("GuiProjectSettings") is not None, timeout=1000) projSettings._doClose()
projEdit = getGuiItem("GuiProjectSettings") # END Test testDlgProjSettings_Replace
assert isinstance(projEdit, GuiProjectSettings)
qtbot.addWidget(projEdit)
assert projEdit.tabMain.editName.text() == "Project Name"
assert projEdit.tabMain.editTitle.text() == "Project Title"
theAuth = projEdit.tabMain.editAuthors.toPlainText().strip().splitlines()
assert len(theAuth) == 2
assert theAuth[0] == "Jane Doe"
assert theAuth[1] == "John Doh"
projEdit._doClose()
qtbot.wait(stepDelay)
assert nwGUI.saveProject()
qtbot.wait(stepDelay)
# Check the files
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, [2, 8, 9, 10])
# qtbot.stopForInteraction()
# END Test testDlgProjSettings_Dialog
+11
View File
@@ -30,6 +30,17 @@ XML_IGNORE = ("<novelWriterXML", "<saveCount", "<autoCount", "<editTime")
class C: class C:
# Import and status items from test project when random generator is mocked
sNew = "s000000"
sNote = "s000001"
sDraft = "s000002"
sFinished = "s000003"
iNew = "i000004"
iMinor = "i000005"
iMajor = "i000006"
iMain = "i000007"
# Handles from test project when random generator is mocked # Handles from test project when random generator is mocked
hInvalid = "0000000000000" hInvalid = "0000000000000"
hNovelRoot = "0000000000008" hNovelRoot = "0000000000008"