Fix and optimise code (#904)
* Fix bug in early error reporting in main init * Update docstrings and optimise code in GuiMain * Update docstrings and optimise code in Config * Update docstrings and optimise code in common module * Update docstrings and optimise code in main project classes * Update the OptionState class * Update the spell checker class * Update the file converter classes and extend tests * Update the about, merge, split and item editor classes and extend tests * Update item editor test * Update about dialog tests * Some minor test cleanup * Fix typo and add clarification in contributing guide
This commit is contained in:
committed by
GitHub
parent
2a06db0a2b
commit
1c45331b0a
@@ -1,115 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="1.5-alpha0" hexVersion="0x010500a0" fileVersion="1.2" timeStamp="2021-08-02 03:04:11">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title></title>
|
||||
<saveCount>2</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
<settings>
|
||||
<doBackup>True</doBackup>
|
||||
<language>None</language>
|
||||
<spellCheck>False</spellCheck>
|
||||
<spellLang>None</spellLang>
|
||||
<autoOutline>True</autoOutline>
|
||||
<lastEdited>0e17daca5f3e1</lastEdited>
|
||||
<lastViewed>None</lastViewed>
|
||||
<lastWordCount>6</lastWordCount>
|
||||
<novelWordCount>6</novelWordCount>
|
||||
<notesWordCount>0</notesWordCount>
|
||||
<autoReplace/>
|
||||
<titleFormat>
|
||||
<title>%title%</title>
|
||||
<chapter>%title%</chapter>
|
||||
<unnumbered>%title%</unnumbered>
|
||||
<scene>* * *</scene>
|
||||
<section></section>
|
||||
</titleFormat>
|
||||
<status>
|
||||
<entry blue="100" green="100" red="100">New</entry>
|
||||
<entry blue="0" green="50" red="200">Note</entry>
|
||||
<entry blue="0" green="150" red="200">Draft</entry>
|
||||
<entry blue="0" green="200" red="50">Finished</entry>
|
||||
</status>
|
||||
<importance>
|
||||
<entry blue="100" green="100" red="100">New</entry>
|
||||
<entry blue="0" green="50" red="200">Minor</entry>
|
||||
<entry blue="0" green="150" red="200">Major</entry>
|
||||
<entry blue="0" green="200" red="50">Main</entry>
|
||||
</importance>
|
||||
</settings>
|
||||
<content count="8">
|
||||
<item handle="73475cb40a568" order="0" parent="None">
|
||||
<name>Novel</name>
|
||||
<type>ROOT</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="25fc0e7096fc6" order="0" parent="73475cb40a568">
|
||||
<name>Title Page</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<exported>True</exported>
|
||||
<layout>DOCUMENT</layout>
|
||||
<charCount>11</charCount>
|
||||
<wordCount>2</wordCount>
|
||||
<paraCount>0</paraCount>
|
||||
<cursorPos>0</cursorPos>
|
||||
</item>
|
||||
<item handle="31489056e0916" order="1" parent="73475cb40a568">
|
||||
<name>New Chapter</name>
|
||||
<type>FOLDER</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="98010bd9270f9" order="0" parent="31489056e0916">
|
||||
<name>New Chapter</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<exported>True</exported>
|
||||
<layout>DOCUMENT</layout>
|
||||
<charCount>11</charCount>
|
||||
<wordCount>2</wordCount>
|
||||
<paraCount>0</paraCount>
|
||||
<cursorPos>0</cursorPos>
|
||||
</item>
|
||||
<item handle="0e17daca5f3e1" order="1" parent="31489056e0916">
|
||||
<name>Just a Page</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>Note</status>
|
||||
<exported>False</exported>
|
||||
<layout>DOCUMENT</layout>
|
||||
<charCount>9</charCount>
|
||||
<wordCount>2</wordCount>
|
||||
<paraCount>0</paraCount>
|
||||
<cursorPos>0</cursorPos>
|
||||
</item>
|
||||
<item handle="44cb730c42048" order="1" parent="None">
|
||||
<name>Plot</name>
|
||||
<type>ROOT</type>
|
||||
<class>PLOT</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="71ee45a3c0db9" order="2" parent="None">
|
||||
<name>Characters</name>
|
||||
<type>ROOT</type>
|
||||
<class>CHARACTER</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="811786ad1ae74" order="3" parent="None">
|
||||
<name>World</name>
|
||||
<type>ROOT</type>
|
||||
<class>WORLD</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
@@ -31,8 +31,8 @@ from tools import writeFile
|
||||
|
||||
from novelwriter.guimain import GuiMain
|
||||
from novelwriter.common import (
|
||||
checkString, checkInt, checkBool, checkHandle, isHandle, isTitleTag,
|
||||
isItemClass, isItemType, isItemLayout, hexToInt, formatInt,
|
||||
checkString, checkInt, checkFloat, checkBool, checkHandle, isHandle,
|
||||
isTitleTag, isItemClass, isItemType, isItemLayout, hexToInt, formatInt,
|
||||
formatTimeStamp, formatTime, parseTimeStamp, splitVersionNumber,
|
||||
transferCase, fuzzyTime, numberToRoman, jsonEncode, readTextFile,
|
||||
makeFileNameSafe, sha256sum, getGuiItem, NWConfigParser
|
||||
@@ -68,6 +68,20 @@ def testBaseCommon_CheckInt():
|
||||
# END Test testBaseCommon_CheckInt
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_CheckFloat():
|
||||
"""Test the checkFloat function.
|
||||
"""
|
||||
assert checkFloat(None, 3.0, True) is None
|
||||
assert checkFloat("None", 3.0, True) is None
|
||||
assert checkFloat(None, 3.0, False) == 3.0
|
||||
assert checkFloat(1, 3.0, False) == 1.0
|
||||
assert checkFloat(1.0, 3.0, False) == 1.0
|
||||
assert checkFloat(True, 3.0, False) == 1.0
|
||||
|
||||
# END Test testBaseCommon_CheckInt
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
def testBaseCommon_CheckBool():
|
||||
"""Test the checkBool function.
|
||||
|
||||
@@ -73,7 +73,7 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, tmpDir):
|
||||
assert theOpts.loadSettings()
|
||||
|
||||
# Check that unwanted items have been removed
|
||||
assert theOpts.theState == {
|
||||
assert theOpts._theState == {
|
||||
"GuiBuildNovel": {
|
||||
"winWidth": 1000,
|
||||
"winHeight": 700,
|
||||
@@ -88,7 +88,7 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, tmpDir):
|
||||
|
||||
# Load again to check we get the values back
|
||||
assert theOpts.loadSettings()
|
||||
assert theOpts.theState == {
|
||||
assert theOpts._theState == {
|
||||
"GuiBuildNovel": {
|
||||
"winWidth": 1000,
|
||||
"winHeight": 700,
|
||||
@@ -129,7 +129,7 @@ def testCoreOptions_SetGet(mockGUI):
|
||||
assert theOpts.getValue("GuiBuildNovel", "mockItem", None) is None
|
||||
|
||||
# Get type-specific
|
||||
assert theOpts.getString("GuiBuildNovel", "winWidth", None) == "100"
|
||||
assert theOpts.getString("GuiBuildNovel", "winWidth", None) is None
|
||||
assert theOpts.getString("GuiBuildNovel", "mockItem", None) is None
|
||||
assert theOpts.getInt("GuiBuildNovel", "winWidth", None) == 100
|
||||
assert theOpts.getInt("GuiBuildNovel", "textFont", None) is None
|
||||
|
||||
@@ -61,7 +61,7 @@ def testCoreSpell_Enchant(monkeypatch, tmpDir):
|
||||
|
||||
assert spChk._readProjectDictionary(None) is False
|
||||
assert spChk._readProjectDictionary(wList) is True
|
||||
assert spChk.projectDict == wList
|
||||
assert spChk._projectDict == wList
|
||||
|
||||
# Cannot write to file
|
||||
with monkeypatch.context() as mp:
|
||||
|
||||
@@ -27,59 +27,6 @@ from tools import readFile
|
||||
from novelwriter.core import NWProject, NWIndex, ToHtml
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Format(mockGUI):
|
||||
"""Test all the formatters for the ToHtml class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theHtml = ToHtml(theProject)
|
||||
|
||||
# Export Mode
|
||||
# ===========
|
||||
|
||||
assert theHtml._formatSynopsis("synopsis text") == (
|
||||
"<p class='synopsis'><strong>Synopsis:</strong> synopsis text</p>\n"
|
||||
)
|
||||
assert theHtml._formatComments("comment text") == (
|
||||
"<p class='comment'><strong>Comment:</strong> comment text</p>\n"
|
||||
)
|
||||
|
||||
assert theHtml._formatKeywords("") == ""
|
||||
assert theHtml._formatKeywords("tag: Jane") == (
|
||||
"<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>"
|
||||
)
|
||||
assert theHtml._formatKeywords("char: Bod, Jane") == (
|
||||
"<span class='tags'>Characters:</span> "
|
||||
"<a href='#tag_Bod'>Bod</a>, "
|
||||
"<a href='#tag_Jane'>Jane</a>"
|
||||
)
|
||||
|
||||
# Preview Mode
|
||||
# ============
|
||||
|
||||
theHtml.setPreview(True, True)
|
||||
|
||||
assert theHtml._formatSynopsis("synopsis text") == (
|
||||
"<p class='comment'><span class='synopsis'>Synopsis:</span> synopsis text</p>\n"
|
||||
)
|
||||
assert theHtml._formatComments("comment text") == (
|
||||
"<p class='comment'>comment text</p>\n"
|
||||
)
|
||||
|
||||
assert theHtml._formatKeywords("") == ""
|
||||
assert theHtml._formatKeywords("tag: Jane") == (
|
||||
"<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>"
|
||||
)
|
||||
assert theHtml._formatKeywords("char: Bod, Jane") == (
|
||||
"<span class='tags'>Characters:</span> "
|
||||
"<a href='#char=Bod'>Bod</a>, "
|
||||
"<a href='#char=Jane'>Jane</a>"
|
||||
)
|
||||
|
||||
# END Test testCoreToHtml_Format
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_ConvertFormat(mockGUI):
|
||||
"""Test the tokenizer and converter chain using the ToHtml class.
|
||||
@@ -433,7 +380,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Complex(mockGUI, fncDir):
|
||||
"""Test the ave method of the ToHtml class.
|
||||
"""Test the save method of the ToHtml class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theHtml = ToHtml(theProject)
|
||||
@@ -524,7 +471,7 @@ def testCoreToHtml_Complex(mockGUI, fncDir):
|
||||
theHtml.saveHTML5(saveFile)
|
||||
assert readFile(saveFile) == htmlDoc
|
||||
|
||||
# END Test testCoreToHtml_Save
|
||||
# END Test testCoreToHtml_Complex
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
@@ -589,3 +536,56 @@ def testCoreToHtml_Methods(mockGUI):
|
||||
assert theHtml.getStyleSheet() == []
|
||||
|
||||
# END Test testCoreToHtml_Methods
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Format(mockGUI):
|
||||
"""Test all the formatters for the ToHtml class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theHtml = ToHtml(theProject)
|
||||
|
||||
# Export Mode
|
||||
# ===========
|
||||
|
||||
assert theHtml._formatSynopsis("synopsis text") == (
|
||||
"<p class='synopsis'><strong>Synopsis:</strong> synopsis text</p>\n"
|
||||
)
|
||||
assert theHtml._formatComments("comment text") == (
|
||||
"<p class='comment'><strong>Comment:</strong> comment text</p>\n"
|
||||
)
|
||||
|
||||
assert theHtml._formatKeywords("") == ""
|
||||
assert theHtml._formatKeywords("tag: Jane") == (
|
||||
"<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>"
|
||||
)
|
||||
assert theHtml._formatKeywords("char: Bod, Jane") == (
|
||||
"<span class='tags'>Characters:</span> "
|
||||
"<a href='#tag_Bod'>Bod</a>, "
|
||||
"<a href='#tag_Jane'>Jane</a>"
|
||||
)
|
||||
|
||||
# Preview Mode
|
||||
# ============
|
||||
|
||||
theHtml.setPreview(True, True)
|
||||
|
||||
assert theHtml._formatSynopsis("synopsis text") == (
|
||||
"<p class='comment'><span class='synopsis'>Synopsis:</span> synopsis text</p>\n"
|
||||
)
|
||||
assert theHtml._formatComments("comment text") == (
|
||||
"<p class='comment'>comment text</p>\n"
|
||||
)
|
||||
|
||||
assert theHtml._formatKeywords("") == ""
|
||||
assert theHtml._formatKeywords("tag: Jane") == (
|
||||
"<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>"
|
||||
)
|
||||
assert theHtml._formatKeywords("char: Bod, Jane") == (
|
||||
"<span class='tags'>Characters:</span> "
|
||||
"<a href='#char=Bod'>Bod</a>, "
|
||||
"<a href='#char=Jane'>Jane</a>"
|
||||
)
|
||||
|
||||
# END Test testCoreToHtml_Format
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
"""
|
||||
novelWriter – ToMd Class Tester
|
||||
===============================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2021, Veronica Berglyd Olsen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from tools import readFile
|
||||
|
||||
from novelwriter.core import NWProject, NWIndex, ToMarkdown
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_ConvertFormat(mockGUI):
|
||||
"""Test the tokenizer and converter chain using the ToMarkdown class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theMD = ToMarkdown(theProject)
|
||||
|
||||
# Headers
|
||||
# =======
|
||||
|
||||
theMD.isNovel = True
|
||||
theMD.isNote = False
|
||||
theMD.isFirst = True
|
||||
|
||||
# Header 1
|
||||
theMD.theText = "# Partition\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "# Partition\n\n"
|
||||
|
||||
# Header 2
|
||||
theMD.theText = "## Chapter Title\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "## Chapter Title\n\n"
|
||||
|
||||
# Header 3
|
||||
theMD.theText = "### Scene Title\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "### Scene Title\n\n"
|
||||
|
||||
# Header 4
|
||||
theMD.theText = "#### Section Title\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "#### Section Title\n\n"
|
||||
|
||||
# Title
|
||||
theMD.theText = "#! Title\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "# Title\n\n"
|
||||
|
||||
# Unnumbered
|
||||
theMD.theText = "##! Prologue\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "## Prologue\n\n"
|
||||
|
||||
# Paragraphs
|
||||
# ==========
|
||||
|
||||
# Text for GitHub Markdown
|
||||
theMD.setGitHubMarkdown()
|
||||
theMD.theText = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == (
|
||||
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
||||
)
|
||||
|
||||
# Text for Standard Markdown
|
||||
theMD.setStandardMarkdown()
|
||||
theMD.theText = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == (
|
||||
"Some **nested bold and _italic_ and strikethrough text** here\n\n"
|
||||
)
|
||||
|
||||
# Text w/Hard Break
|
||||
theMD.theText = "Line one \nLine two \nLine three\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "Line one \nLine two \nLine three\n\n"
|
||||
|
||||
# Synopsis
|
||||
theMD.theText = "%synopsis: The synopsis ...\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == ""
|
||||
|
||||
theMD.setSynopsis(True)
|
||||
theMD.theText = "%synopsis: The synopsis ...\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "**Synopsis:** The synopsis ...\n\n"
|
||||
|
||||
# Comment
|
||||
theMD.theText = "% A comment ...\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == ""
|
||||
|
||||
theMD.setComments(True)
|
||||
theMD.theText = "% A comment ...\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "**Comment:** A comment ...\n\n"
|
||||
|
||||
# Keywords
|
||||
theMD.theText = "@char: Bod, Jane\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == ""
|
||||
|
||||
theMD.setKeywords(True)
|
||||
theMD.theText = "@char: Bod, Jane\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "**Characters:** Bod, Jane\n\n"
|
||||
|
||||
# Multiple Keywords
|
||||
theMD.setKeywords(True)
|
||||
theMD.theText = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == (
|
||||
"## Chapter\n\n"
|
||||
"**Point of View:** Bod \n"
|
||||
"**Plot:** Main \n"
|
||||
"**Locations:** Europe\n\n"
|
||||
)
|
||||
|
||||
# END Test testCoreToMarkdown_ConvertFormat
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_ConvertDirect(mockGUI):
|
||||
"""Test the converter directly using the ToMarkdown class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theMD = ToMarkdown(theProject)
|
||||
|
||||
theMD.isNovel = True
|
||||
theMD.isNote = False
|
||||
|
||||
# Special Titles
|
||||
# ==============
|
||||
|
||||
# Title
|
||||
theMD.theTokens = [
|
||||
(theMD.T_TITLE, 1, "A Title", None, theMD.A_PBB | theMD.A_CENTRE),
|
||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
||||
]
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "# A Title\n\n"
|
||||
|
||||
# Unnumbered
|
||||
theMD.theTokens = [
|
||||
(theMD.T_UNNUM, 1, "Prologue", None, theMD.A_PBB),
|
||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
||||
]
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "## Prologue\n\n"
|
||||
|
||||
# Separators
|
||||
# ==========
|
||||
|
||||
# Separator
|
||||
theMD.theTokens = [
|
||||
(theMD.T_SEP, 1, "* * *", None, theMD.A_CENTRE),
|
||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
||||
]
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "* * *\n\n"
|
||||
|
||||
# Skip
|
||||
theMD.theTokens = [
|
||||
(theMD.T_SKIP, 1, "", None, theMD.A_NONE),
|
||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
||||
]
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == "\n\n\n"
|
||||
|
||||
# END Test testCoreToMarkdown_ConvertDirect
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_Complex(mockGUI, fncDir):
|
||||
"""Test the save method of the ToMarkdown class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theMD = ToMarkdown(theProject)
|
||||
theMD.isNovel = True
|
||||
|
||||
# Build Project
|
||||
# =============
|
||||
|
||||
docText = [
|
||||
"# My Novel\n**By Jane Doh**\n",
|
||||
"## Chapter 1\n\nThe text of chapter one.\n",
|
||||
"### Scene 1\n\nThe text of scene one.\n",
|
||||
"#### A Section\n\nMore text in scene one.\n",
|
||||
"## Chapter 2\n\nThe text of chapter two.\n",
|
||||
"### Scene 2\n\nThe text of scene two.\n",
|
||||
"#### A Section\n\n\tMore text in scene two.\n",
|
||||
]
|
||||
resText = [
|
||||
"# My Novel\n\n**By Jane Doh**\n\n",
|
||||
"## Chapter 1\n\nThe text of chapter one.\n\n",
|
||||
"### Scene 1\n\nThe text of scene one.\n\n",
|
||||
"#### A Section\n\nMore text in scene one.\n\n",
|
||||
"## Chapter 2\n\nThe text of chapter two.\n\n",
|
||||
"### Scene 2\n\nThe text of scene two.\n\n",
|
||||
"#### A Section\n\n\tMore text in scene two.\n\n",
|
||||
]
|
||||
|
||||
for i in range(len(docText)):
|
||||
theMD.theText = docText[i]
|
||||
theMD.doPreProcessing()
|
||||
theMD.tokenizeText()
|
||||
theMD.doConvert()
|
||||
assert theMD.theResult == resText[i]
|
||||
|
||||
assert theMD.fullMD == resText
|
||||
assert theMD.getFullResultSize() == len("".join(resText))
|
||||
|
||||
theMD.replaceTabs(nSpaces=4, spaceChar=" ")
|
||||
resText[6] = "#### A Section\n\n More text in scene two.\n\n"
|
||||
|
||||
# Check File
|
||||
# ==========
|
||||
|
||||
saveFile = os.path.join(fncDir, "outFile.md")
|
||||
theMD.saveMarkdown(saveFile)
|
||||
assert readFile(saveFile) == "".join(resText)
|
||||
|
||||
# END Test testCoreToHtml_Complex
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_Format(mockGUI):
|
||||
"""Test all the formatters for the ToMarkdown class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theMD = ToMarkdown(theProject)
|
||||
|
||||
assert theMD._formatKeywords("", theMD.A_NONE) == ""
|
||||
assert theMD._formatKeywords("tag: Jane", theMD.A_NONE) == "**Tag:** Jane\n\n"
|
||||
assert theMD._formatKeywords("tag: Jane, John", theMD.A_NONE) == "**Tag:** Jane, John\n\n"
|
||||
assert theMD._formatKeywords("tag: Jane", theMD.A_Z_BTMMRG) == "**Tag:** Jane \n"
|
||||
|
||||
# END Test testCoreToMarkdown_Format
|
||||
@@ -559,6 +559,62 @@ def testCoreToOdt_Convert(mockGUI):
|
||||
# END Test testCoreToOdt_Convert
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToOdt_ConvertDirect(mockGUI):
|
||||
"""Test the converter directly using the ToOdt class to reach some
|
||||
otherwise hard to reach conditions.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theDoc = ToOdt(theProject, isFlat=True)
|
||||
|
||||
theDoc.isNovel = True
|
||||
|
||||
# Justified
|
||||
theDoc = ToOdt(theProject, isFlat=True)
|
||||
theDoc.theTokens = [
|
||||
(theDoc.T_TEXT, 1, "This is a paragraph", [], theDoc.A_JUSTIFY),
|
||||
(theDoc.T_EMPTY, 1, "", None, theDoc.A_NONE),
|
||||
]
|
||||
theDoc.initDocument()
|
||||
theDoc.doConvert()
|
||||
theDoc.closeDocument()
|
||||
assert (
|
||||
'<style:style style:name="P1" style:family="paragraph" '
|
||||
'style:parent-style-name="Text_Body">'
|
||||
'<style:paragraph-properties fo:text-align="justify"/>'
|
||||
'</style:style>'
|
||||
) in xmlToText(theDoc._xAuto)
|
||||
assert xmlToText(theDoc._xText) == (
|
||||
'<office:text>'
|
||||
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
||||
'</office:text>'
|
||||
)
|
||||
|
||||
# Page Break After
|
||||
theDoc = ToOdt(theProject, isFlat=True)
|
||||
theDoc.theTokens = [
|
||||
(theDoc.T_TEXT, 1, "This is a paragraph", [], theDoc.A_PBA),
|
||||
(theDoc.T_EMPTY, 1, "", None, theDoc.A_NONE),
|
||||
]
|
||||
theDoc.initDocument()
|
||||
theDoc.doConvert()
|
||||
theDoc.closeDocument()
|
||||
assert (
|
||||
'<style:style style:name="P1" style:family="paragraph" '
|
||||
'style:parent-style-name="Text_Body">'
|
||||
'<style:paragraph-properties fo:break-after="page"/>'
|
||||
'</style:style>'
|
||||
) in xmlToText(theDoc._xAuto)
|
||||
assert xmlToText(theDoc._xText) == (
|
||||
'<office:text>'
|
||||
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
||||
'</office:text>'
|
||||
)
|
||||
|
||||
# END Test testCoreToOdt_ConvertDirect
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToOdt_SaveFlat(mockGUI, fncDir, outDir, refDir):
|
||||
"""Test the document save functions.
|
||||
@@ -676,6 +732,36 @@ def testCoreToOdt_SaveFull(mockGUI, fncDir, outDir, refDir):
|
||||
# END Test testCoreToOdt_SaveFull
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToOdt_Format(mockGUI):
|
||||
"""Test the formatters for the ToOdt class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
mockGUI.theIndex = NWIndex(theProject)
|
||||
theDoc = ToOdt(theProject, isFlat=True)
|
||||
|
||||
assert theDoc._formatSynopsis("synopsis text") == (
|
||||
"**Synopsis:** synopsis text",
|
||||
"_B b_ "
|
||||
)
|
||||
assert theDoc._formatComments("comment text") == (
|
||||
"**Comment:** comment text",
|
||||
"_B b_ "
|
||||
)
|
||||
|
||||
assert theDoc._formatKeywords("") == ""
|
||||
assert theDoc._formatKeywords("tag: Jane") == (
|
||||
"**Tag:** Jane",
|
||||
"_B b_ "
|
||||
)
|
||||
assert theDoc._formatKeywords("char: Bod, Jane") == (
|
||||
"**Characters:** Bod, Jane",
|
||||
"_B b_ "
|
||||
)
|
||||
|
||||
# END Test testCoreToOdt_Format
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToOdt_ODTParagraphStyle():
|
||||
"""Test the ODTParagraphStyle class.
|
||||
|
||||
@@ -27,23 +27,22 @@ from PyQt5.QtWidgets import QAction, QMessageBox
|
||||
|
||||
from novelwriter.dialogs import GuiAbout
|
||||
|
||||
keyDelay = 2
|
||||
typeDelay = 1
|
||||
stepDelay = 20
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgAbout_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
"""Test the full about dialogs.
|
||||
def testDlgAbout_NWDialog(qtbot, monkeypatch, nwGUI):
|
||||
"""Test the novelWriter about dialogs.
|
||||
"""
|
||||
# NW About
|
||||
monkeypatch.setattr(GuiAbout, "exec_", lambda *a: None)
|
||||
nwGUI.mainMenu.aAboutNW.activate(QAction.Trigger)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiAbout") is not None, timeout=1000)
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
|
||||
# NW About
|
||||
nwGUI.theTheme.themeName = "A Theme"
|
||||
nwGUI.theTheme.themeAuthor = "An Author"
|
||||
assert nwGUI.showAboutNWDialog(showNotes=True) is True
|
||||
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiAbout") is not None, timeout=1000)
|
||||
msgAbout = getGuiItem("GuiAbout")
|
||||
assert isinstance(msgAbout, GuiAbout)
|
||||
msgAbout.show()
|
||||
|
||||
assert msgAbout.pageAbout.document().characterCount() > 100
|
||||
assert msgAbout.pageNotes.document().characterCount() > 100
|
||||
@@ -59,12 +58,29 @@ def testDlgAbout_Dialog(qtbot, monkeypatch, nwGUI):
|
||||
|
||||
msgAbout.showReleaseNotes()
|
||||
assert msgAbout.tabBox.currentWidget() == msgAbout.pageNotes
|
||||
|
||||
# Qt About
|
||||
monkeypatch.setattr(QMessageBox, "aboutQt", lambda *a, **k: None)
|
||||
nwGUI.mainMenu.aAboutQt.activate(QAction.Trigger)
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
msgAbout._doClose()
|
||||
|
||||
# END Test testDlgAbout_Dialog
|
||||
# Open Again from Menu
|
||||
nwGUI.mainMenu.aAboutNW.activate(QAction.Trigger)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiAbout") is not None, timeout=1000)
|
||||
msgAbout = getGuiItem("GuiAbout")
|
||||
assert msgAbout is not None
|
||||
msgAbout._doClose()
|
||||
|
||||
# END Test testDlgAbout_NWDialog
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgAbout_QtDialog(monkeypatch, nwGUI):
|
||||
"""Test the Qt about dialogs.
|
||||
"""
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(QMessageBox, "aboutQt", lambda *a, **k: None)
|
||||
|
||||
# Open About
|
||||
# All it can do is check aigainst a crash
|
||||
assert nwGUI.showAboutQtDialog() is True
|
||||
nwGUI.mainMenu.aAboutQt.activate(QAction.Trigger)
|
||||
|
||||
# END Test testDlgAbout_QtDialog
|
||||
|
||||
@@ -31,10 +31,6 @@ from novelwriter.dialogs import GuiDocMerge, GuiItemEditor
|
||||
from novelwriter.enum import nwItemType, nwWidget
|
||||
from novelwriter.core.tree import NWTree
|
||||
|
||||
keyDelay = 2
|
||||
typeDelay = 1
|
||||
stepDelay = 20
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
@@ -96,7 +92,7 @@ def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
nwMerge = getGuiItem("GuiDocMerge")
|
||||
assert isinstance(nwMerge, GuiDocMerge)
|
||||
nwMerge.show()
|
||||
qtbot.wait(stepDelay)
|
||||
qtbot.wait(50)
|
||||
|
||||
# Populate List
|
||||
# =============
|
||||
@@ -32,10 +32,6 @@ from novelwriter.enum import nwItemType, nwWidget
|
||||
from novelwriter.core.document import NWDoc
|
||||
from novelwriter.core.tree import NWTree
|
||||
|
||||
keyDelay = 2
|
||||
typeDelay = 1
|
||||
stepDelay = 20
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
@@ -103,7 +99,7 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
nwSplit = getGuiItem("GuiDocSplit")
|
||||
assert isinstance(nwSplit, GuiDocSplit)
|
||||
nwSplit.show()
|
||||
qtbot.wait(stepDelay)
|
||||
qtbot.wait(50)
|
||||
|
||||
# Populate List
|
||||
# =============
|
||||
@@ -253,7 +249,7 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
nwSplit.sourceItem = None
|
||||
assert nwSplit._doSplit() is False
|
||||
|
||||
# Close up
|
||||
# Close
|
||||
nwSplit._doClose()
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
@@ -20,93 +20,213 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import os
|
||||
|
||||
from shutil import copyfile
|
||||
from tools import cmpFiles, getGuiItem
|
||||
from tools import getGuiItem
|
||||
|
||||
from PyQt5.QtWidgets import QAction, QMessageBox
|
||||
from PyQt5.QtWidgets import QAction, QDialog, QMessageBox
|
||||
|
||||
from novelwriter.gui import GuiProjectTree
|
||||
from novelwriter.enum import nwItemLayout
|
||||
from novelwriter.enum import nwItemLayout, nwItemType
|
||||
from novelwriter.dialogs import GuiItemEditor
|
||||
|
||||
keyDelay = 2
|
||||
typeDelay = 1
|
||||
stepDelay = 20
|
||||
from novelwriter.core.tree import NWTree
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir):
|
||||
"""Test the full item editor dialog.
|
||||
def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
"""Test launching the item editor dialog from GuiMain.
|
||||
"""
|
||||
projFile = os.path.join(fncProj, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "guiItemEditor_Dialog_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "guiItemEditor_Dialog_nwProject.nwx")
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
|
||||
# Block Dialog exec_
|
||||
monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: None)
|
||||
|
||||
# Open Editor wo/Project
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Create and Open Project
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
|
||||
# No Selection
|
||||
nwGUI.treeView.clearSelection()
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Force opening from editor
|
||||
assert nwGUI.openDocument("0e17daca5f3e1")
|
||||
nwGUI.isFocusMode = True
|
||||
|
||||
# Block Tree Lookup
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(NWTree, "__getitem__", lambda *a: None)
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Invalid Type
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"].itemType = nwItemType.NO_TYPE
|
||||
assert nwGUI.editItem() is False
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"].itemType = nwItemType.FILE
|
||||
|
||||
# Open Properly
|
||||
assert nwGUI.editItem() is True
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiItemEditor") is not None, timeout=1000)
|
||||
itemEdit = getGuiItem("GuiItemEditor")
|
||||
assert itemEdit is not None
|
||||
itemEdit.close()
|
||||
|
||||
# Open Via Menu
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr(GuiItemEditor, "result", lambda *a: QDialog.Accepted)
|
||||
nwGUI.mainMenu.aEditItem.activate(QAction.Trigger)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiItemEditor") is not None, timeout=1000)
|
||||
itemEdit = getGuiItem("GuiItemEditor")
|
||||
assert itemEdit is not None
|
||||
itemEdit.close()
|
||||
|
||||
nwGUI.isFocusMode = False
|
||||
|
||||
# END Test testDlgItemEditor_Dialog
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgItemEditor_Novel(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
"""Test the item editor dialog for a novel document.
|
||||
"""
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create new, save, open project
|
||||
# Create Project and Open Document
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
assert nwGUI.openDocument("0e17daca5f3e1")
|
||||
assert nwGUI.treeView.setSelectedHandle("0e17daca5f3e1", doScroll=True)
|
||||
|
||||
monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: None)
|
||||
nwGUI.mainMenu.aEditItem.activate(QAction.Trigger)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiItemEditor") is not None, timeout=1000)
|
||||
# Check that an invalid handle is managed
|
||||
itemEdit = GuiItemEditor(nwGUI, "whatever")
|
||||
itemEdit.show()
|
||||
itemEdit._doClose()
|
||||
|
||||
itemEdit = getGuiItem("GuiItemEditor")
|
||||
assert isinstance(itemEdit, GuiItemEditor)
|
||||
# Edit a Document
|
||||
itemEdit = GuiItemEditor(nwGUI, "0e17daca5f3e1")
|
||||
itemEdit.show()
|
||||
|
||||
qtbot.addWidget(itemEdit)
|
||||
|
||||
# Check Existing Settings
|
||||
assert itemEdit.editName.text() == "New Scene"
|
||||
assert itemEdit.editStatus.currentData() == "New"
|
||||
assert itemEdit.editLayout.currentData() == nwItemLayout.DOCUMENT
|
||||
assert itemEdit.editExport.isChecked() is True
|
||||
|
||||
for c in "Just a Page":
|
||||
qtbot.keyClick(itemEdit.editName, c, delay=typeDelay)
|
||||
# Change Settings
|
||||
layoutIdx = itemEdit.editLayout.findData(nwItemLayout.NOTE)
|
||||
itemEdit.editName.setText("Great Scene")
|
||||
itemEdit.editStatus.setCurrentIndex(1)
|
||||
layoutIdx = itemEdit.editLayout.findData(nwItemLayout.DOCUMENT)
|
||||
itemEdit.editLayout.setCurrentIndex(layoutIdx)
|
||||
|
||||
itemEdit.editExport.setChecked(False)
|
||||
assert not itemEdit.editExport.isChecked()
|
||||
|
||||
# Check New Settings
|
||||
itemEdit._doSave()
|
||||
assert itemEdit.theItem.itemName == "Great Scene"
|
||||
assert itemEdit.theItem.itemStatus == "Note"
|
||||
assert itemEdit.theItem.itemLayout == nwItemLayout.NOTE
|
||||
assert itemEdit.theItem.isExported is False
|
||||
|
||||
nwGUI.mainMenu.aEditItem.activate(QAction.Trigger)
|
||||
qtbot.waitUntil(lambda: getGuiItem("GuiItemEditor") is not None, timeout=1000)
|
||||
|
||||
itemEdit = getGuiItem("GuiItemEditor")
|
||||
assert isinstance(itemEdit, GuiItemEditor)
|
||||
itemEdit.show()
|
||||
|
||||
qtbot.addWidget(itemEdit)
|
||||
assert itemEdit.editName.text() == "Just a Page"
|
||||
assert itemEdit.editStatus.currentData() == "Note"
|
||||
assert itemEdit.editLayout.currentData() == nwItemLayout.DOCUMENT
|
||||
itemEdit._doClose()
|
||||
|
||||
# Check that the header is updated
|
||||
# Check that the editor header is updated
|
||||
nwGUI.docEditor.updateDocInfo("0e17daca5f3e1")
|
||||
assert nwGUI.docEditor.docHeader.theTitle.text() == "Novel › New Chapter › Just a Page"
|
||||
assert not nwGUI.docEditor.setCursorLine("where?")
|
||||
assert nwGUI.docEditor.setCursorLine(2)
|
||||
qtbot.wait(stepDelay)
|
||||
assert nwGUI.docEditor.getCursorPosition() == 15
|
||||
|
||||
qtbot.wait(stepDelay)
|
||||
assert nwGUI.saveProject()
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Check the files
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
|
||||
assert nwGUI.docEditor.docHeader.theTitle.text() == "Novel › New Chapter › Great Scene"
|
||||
|
||||
itemEdit.close()
|
||||
del itemEdit
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
# END Test testDlgItemEditor_Dialog
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgItemEditor_Note(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
"""Test the item editor dialog for a project note.
|
||||
"""
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create Project and Open Document
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
|
||||
# Create Note
|
||||
nwGUI.treeView.clearSelection()
|
||||
nwGUI.treeView._getTreeItem("71ee45a3c0db9").setSelected(True)
|
||||
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
|
||||
|
||||
# Open Note
|
||||
assert nwGUI.openDocument("1a6562590ef19")
|
||||
|
||||
# Edit a Document
|
||||
itemEdit = GuiItemEditor(nwGUI, "1a6562590ef19")
|
||||
itemEdit.show()
|
||||
|
||||
# Check Existing Settings
|
||||
assert itemEdit.editName.text() == "New File"
|
||||
assert itemEdit.editStatus.currentData() == "New"
|
||||
assert itemEdit.editLayout.currentData() == nwItemLayout.NOTE
|
||||
assert itemEdit.editExport.isChecked() is True
|
||||
|
||||
# Change Settings
|
||||
itemEdit.editName.setText("New Character")
|
||||
itemEdit.editStatus.setCurrentIndex(1)
|
||||
itemEdit.editExport.setChecked(False)
|
||||
|
||||
# Check New Settings
|
||||
itemEdit._doSave()
|
||||
assert itemEdit.theItem.itemName == "New Character"
|
||||
assert itemEdit.theItem.itemStatus == "Minor"
|
||||
assert itemEdit.theItem.itemLayout == nwItemLayout.NOTE
|
||||
assert itemEdit.theItem.isExported is False
|
||||
|
||||
itemEdit.close()
|
||||
del itemEdit
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
# END Test testDlgItemEditor_Note
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testDlgItemEditor_Folder(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
"""Test the item editor dialog for a folder.
|
||||
"""
|
||||
# Block message box
|
||||
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||
|
||||
# Create Project and Open Document
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject({"projPath": fncProj})
|
||||
|
||||
# Edit a Folder
|
||||
itemEdit = GuiItemEditor(nwGUI, "31489056e0916")
|
||||
itemEdit.show()
|
||||
|
||||
# Check Existing Settings
|
||||
assert itemEdit.editName.text() == "New Chapter"
|
||||
assert itemEdit.editStatus.currentData() == "New"
|
||||
assert itemEdit.editLayout.currentData() == nwItemLayout.NO_LAYOUT
|
||||
assert itemEdit.editExport.isChecked() is False
|
||||
|
||||
assert itemEdit.editLayout.isEnabled() is False
|
||||
assert itemEdit.editExport.isEnabled() is False
|
||||
|
||||
# Change Settings
|
||||
itemEdit.editName.setText("Chapter One")
|
||||
itemEdit.editStatus.setCurrentIndex(1)
|
||||
|
||||
# Check New Settings
|
||||
itemEdit._doSave()
|
||||
assert itemEdit.theItem.itemName == "Chapter One"
|
||||
assert itemEdit.theItem.itemStatus == "Note"
|
||||
assert itemEdit.theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||
assert itemEdit.theItem.isExported is False
|
||||
|
||||
itemEdit.close()
|
||||
del itemEdit
|
||||
# qtbot.stopForInteraction()
|
||||
|
||||
# END Test testDlgItemEditor_Folder
|
||||
|
||||
Reference in New Issue
Block a user