Merge pull request #9 from vkbo/test_coverage
Test coverage Merging now that GUI tests work on Travis.
This commit is contained in:
+15
-5
@@ -1,20 +1,30 @@
|
||||
dist: xenial # required for Python >= 3.7
|
||||
os: linux
|
||||
dist: xenial
|
||||
services:
|
||||
- xvfb
|
||||
language: python
|
||||
cache: bundler
|
||||
sudo: required
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libenchant-dev
|
||||
- python3-pyqt5
|
||||
- python3-pyqt5.qtsvg
|
||||
python:
|
||||
# - "3.5"
|
||||
# - "3.6"
|
||||
- "3.5"
|
||||
- "3.7"
|
||||
# - "3.8-dev"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
# - pip install pytest-faulthandler
|
||||
- pip install pytest-xvfb
|
||||
- pip install pytest-cov
|
||||
- pip install pytest-qt
|
||||
- pip install codecov
|
||||
script:
|
||||
- python -m pytest --cov=nw -v
|
||||
- python -m pytest --cov=nw -m "project|core|gui" -v
|
||||
after_success:
|
||||
- codecov
|
||||
after_failure:
|
||||
- cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes
|
||||
|
||||
|
||||
+13
-9
@@ -15,7 +15,7 @@ import getopt
|
||||
|
||||
from os import path, remove, rename
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from nw.main import NovelWriter
|
||||
from nw.gui.winmain import GuiMain
|
||||
from nw.config import Config
|
||||
|
||||
__package__ = "novelWriter"
|
||||
@@ -78,7 +78,7 @@ def main(sysArgs):
|
||||
"logfile=",
|
||||
"version",
|
||||
"config=",
|
||||
"headless",
|
||||
"testmode",
|
||||
]
|
||||
|
||||
helpMsg = (
|
||||
@@ -111,7 +111,7 @@ def main(sysArgs):
|
||||
toStd = True
|
||||
showTime = False
|
||||
confPath = None
|
||||
showGUI = True
|
||||
testMode = False
|
||||
debugGUI = False
|
||||
|
||||
# Parse Options
|
||||
@@ -143,15 +143,15 @@ def main(sysArgs):
|
||||
showTime = True
|
||||
elif inOpt in ("--config"):
|
||||
confPath = inArg
|
||||
elif inOpt in ("--headless"):
|
||||
showGUI = False
|
||||
elif inOpt in ("--testmode"):
|
||||
testMode = True
|
||||
elif inOpt in ("-D","--debuggui"):
|
||||
debugLevel = logging.DEBUG
|
||||
debugStr = "{name:>20}:{lineno:<4d} {levelname:8} {message:}"
|
||||
debugGUI = True
|
||||
|
||||
# Set Config Options
|
||||
CONFIG.showGUI = showGUI
|
||||
CONFIG.showGUI = not testMode
|
||||
CONFIG.debugGUI = debugGUI
|
||||
|
||||
# Set Logging
|
||||
@@ -179,8 +179,12 @@ def main(sysArgs):
|
||||
|
||||
CONFIG.initConfig(confPath)
|
||||
|
||||
nwApp = QApplication([])
|
||||
nwGUI = NovelWriter()
|
||||
exit(nwApp.exec_())
|
||||
if testMode:
|
||||
nwGUI = GuiMain()
|
||||
return nwGUI
|
||||
else:
|
||||
nwApp = QApplication([])
|
||||
nwGUI = GuiMain()
|
||||
exit(nwApp.exec_())
|
||||
|
||||
return
|
||||
|
||||
+15
-8
@@ -117,7 +117,11 @@ class Config:
|
||||
|
||||
logger.debug("Loading config file")
|
||||
confParser = configparser.ConfigParser()
|
||||
confParser.read_file(open(path.join(self.confPath,self.confFile)))
|
||||
try:
|
||||
confParser.read_file(open(path.join(self.confPath,self.confFile)))
|
||||
except Exception as e:
|
||||
logger.error("Could not load config file")
|
||||
return False
|
||||
|
||||
# Get options
|
||||
|
||||
@@ -182,7 +186,7 @@ class Config:
|
||||
if confParser.has_option(cnfSec,"recent%d" % i):
|
||||
self.recentList[i] = confParser.get(cnfSec,"recent%d" % i)
|
||||
|
||||
return
|
||||
return True
|
||||
|
||||
def saveConfig(self):
|
||||
|
||||
@@ -266,13 +270,14 @@ class Config:
|
||||
return
|
||||
|
||||
def setConfPath(self, newPath):
|
||||
if newPath is None: return
|
||||
if newPath is None:
|
||||
return True
|
||||
if not path.isfile(newPath):
|
||||
logger.error("Config: File not found. Using default config path instead.")
|
||||
return
|
||||
return False
|
||||
self.confPath = path.dirname(newPath)
|
||||
self.confFile = path.basename(newPath)
|
||||
return
|
||||
return True
|
||||
|
||||
def setWinSize(self, newWidth, newHeight):
|
||||
if abs(self.winGeometry[self.WIN_WIDTH] - newWidth) >= 10:
|
||||
@@ -281,14 +286,16 @@ class Config:
|
||||
if abs(self.winGeometry[self.WIN_HEIGHT] - newHeight) >= 10:
|
||||
self.winGeometry[self.WIN_HEIGHT] = newHeight
|
||||
self.confChanged = True
|
||||
return
|
||||
return True
|
||||
|
||||
def setTreeColWidths(self, colWidths):
|
||||
self.treeColWidth = colWidths
|
||||
return
|
||||
self.confChanged = True
|
||||
return True
|
||||
|
||||
def setMainPanePos(self, panePos):
|
||||
self.mainPanePos = panePos
|
||||
return
|
||||
self.confChanged = True
|
||||
return True
|
||||
|
||||
# End Class Config
|
||||
|
||||
+11
-10
@@ -282,20 +282,21 @@ class GuiDocTree(QTreeWidget):
|
||||
|
||||
def propagateCount(self, tHandle, theCount, nDepth=0):
|
||||
tItem = self._getTreeItem(tHandle)
|
||||
tItem.setText(self.C_COUNT,str(theCount))
|
||||
pItem = tItem.parent()
|
||||
if pItem is not None:
|
||||
pCount = 0
|
||||
for i in range(pItem.childCount()):
|
||||
pCount += int(pItem.child(i).text(self.C_COUNT))
|
||||
pHandle = pItem.text(self.C_HANDLE)
|
||||
if not nDepth > 200 and pHandle != "":
|
||||
self.propagateCount(pHandle, pCount, nDepth+1)
|
||||
if tItem is not None:
|
||||
tItem.setText(self.C_COUNT,str(theCount))
|
||||
pItem = tItem.parent()
|
||||
if pItem is not None:
|
||||
pCount = 0
|
||||
for i in range(pItem.childCount()):
|
||||
pCount += int(pItem.child(i).text(self.C_COUNT))
|
||||
pHandle = pItem.text(self.C_HANDLE)
|
||||
if not nDepth > 200 and pHandle != "":
|
||||
self.propagateCount(pHandle, pCount, nDepth+1)
|
||||
return
|
||||
|
||||
def buildTree(self):
|
||||
self.clear()
|
||||
for tHandle in self.theProject.projTree:
|
||||
for tHandle in self.theProject.treeOrder:
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
self._addTreeItem(nwItem)
|
||||
return True
|
||||
|
||||
+6
-5
@@ -170,7 +170,7 @@ class GuiMain(QMainWindow):
|
||||
if self.saveProject():
|
||||
self.theProject.newProject()
|
||||
self.treeView.buildTree()
|
||||
return
|
||||
return True
|
||||
|
||||
def openProject(self, projFile=None):
|
||||
if projFile is None:
|
||||
@@ -207,7 +207,7 @@ class GuiMain(QMainWindow):
|
||||
self.stackPane.setCurrentIndex(self.stackDoc)
|
||||
self.docEditor.setText(self.theDocument.openDocument(tHandle))
|
||||
self.docEditor.changeWidth()
|
||||
return
|
||||
return True
|
||||
|
||||
def saveDocument(self):
|
||||
if self.theDocument.theItem is not None:
|
||||
@@ -217,7 +217,7 @@ class GuiMain(QMainWindow):
|
||||
self.theDocument.theItem.setParaCount(self.docEditor.paraCount)
|
||||
self.theDocument.saveDocument(docHtml)
|
||||
self.docEditor.setDocumentChanged(False)
|
||||
return
|
||||
return True
|
||||
|
||||
def _previewDocument(self):
|
||||
|
||||
@@ -246,7 +246,7 @@ class GuiMain(QMainWindow):
|
||||
tHandle = self.treeView.getSelectedHandle()
|
||||
if tHandle is None:
|
||||
logger.warning("No item selected")
|
||||
return
|
||||
return False
|
||||
|
||||
logger.verbose("Opening item %s" % tHandle)
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
@@ -255,7 +255,8 @@ class GuiMain(QMainWindow):
|
||||
self.openDocument(tHandle)
|
||||
else:
|
||||
logger.verbose("Requested item %s is not a file" % tHandle)
|
||||
return
|
||||
|
||||
return True
|
||||
|
||||
def editItem(self):
|
||||
tHandle = self.treeView.getSelectedHandle()
|
||||
|
||||
@@ -78,6 +78,6 @@ class WordCounter(QThread):
|
||||
self.paraCount += 1
|
||||
prevEmpty = countPara == False
|
||||
|
||||
pass
|
||||
return
|
||||
|
||||
## END Class _WordCounter
|
||||
## END Class WordCounter
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Main Class
|
||||
|
||||
novelWriter – Main Class
|
||||
==========================
|
||||
Sets up the main GUI and holds action and event functions
|
||||
|
||||
File History:
|
||||
Created: 2018-09-22 [0.0.1]
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import nw
|
||||
|
||||
from nw.gui.winmain import GuiMain
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class NovelWriter():
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.winMain = GuiMain()
|
||||
|
||||
return
|
||||
|
||||
# END Class NovelWriter
|
||||
@@ -0,0 +1,6 @@
|
||||
[pytest]
|
||||
markers =
|
||||
project: Project classes tests
|
||||
core: Core functionality tests
|
||||
gui: Qt5 GUI tests
|
||||
serial
|
||||
+12
-2
@@ -11,8 +11,18 @@ def ensureDir(theDir):
|
||||
return
|
||||
|
||||
def cmpFiles(fileOne, fileTwo, ignoreLines=[]):
|
||||
foOne = open(fileOne,mode="r")
|
||||
foTwo = open(fileTwo,mode="r")
|
||||
|
||||
try:
|
||||
foOne = open(fileOne,mode="r")
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return False
|
||||
|
||||
try:
|
||||
foTwo = open(fileTwo,mode="r")
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return False
|
||||
|
||||
txtOne = foOne.readlines()
|
||||
txtTwo = foTwo.readlines()
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Hello World!
|
||||
|
||||
## With a Subtitle
|
||||
|
||||
### An Even Subier Title
|
||||
|
||||
#### Basically Not a Title at All
|
||||
|
||||
% How about a comment?
|
||||
@keyword: value
|
||||
|
||||
This is a paragraph of dummy text.
|
||||
|
||||
This is another paragraph of much longer dummy text. It is in fact very very dumb dummy text! We can also try replacing “quotes”, even single’s quotes are replaced. We can hyphen-ate, make dashes – and even longer dashes — if we want. Ellipsis? Not a problem either …
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="0.1.2" fileVersion="1.0" timeStamp="2019-05-16 22:37:13">
|
||||
<project>
|
||||
<name></name>
|
||||
<title></title>
|
||||
</project>
|
||||
<settings>
|
||||
<spellCheck>False</spellCheck>
|
||||
</settings>
|
||||
<content count="6">
|
||||
<item handle="73475cb40a568" order="0" parent="None">
|
||||
<name>Novel</name>
|
||||
<type>ROOT</type>
|
||||
<class>NOVEL</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="25fc0e7096fc6" order="0" parent="73475cb40a568">
|
||||
<name>New Chapter</name>
|
||||
<type>FOLDER</type>
|
||||
<class>NOVEL</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="31489056e0916" order="0" parent="25fc0e7096fc6">
|
||||
<name>New Scene</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>0</charCount>
|
||||
<wordCount>0</wordCount>
|
||||
<paraCount>0</paraCount>
|
||||
</item>
|
||||
<item handle="44cb730c42048" order="1" parent="None">
|
||||
<name>Characters</name>
|
||||
<type>ROOT</type>
|
||||
<class>CHARACTER</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="71ee45a3c0db9" order="2" parent="None">
|
||||
<name>Plot</name>
|
||||
<type>ROOT</type>
|
||||
<class>PLOT</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="811786ad1ae74" order="3" parent="None">
|
||||
<name>World</name>
|
||||
<type>ROOT</type>
|
||||
<class>WORLD</class>
|
||||
<status>0</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
@@ -2,10 +2,11 @@
|
||||
"""novelWriter Common Class Tester
|
||||
"""
|
||||
|
||||
import nw
|
||||
import nw, pytest
|
||||
from nw.common import *
|
||||
from nwtools import cmpList
|
||||
|
||||
@pytest.mark.core
|
||||
def testCheckString():
|
||||
assert checkString(None, "NotNone",True) is None
|
||||
assert checkString("None","NotNone",True) is None
|
||||
@@ -15,6 +16,7 @@ def testCheckString():
|
||||
assert checkString(1.0, "NotNone",False) == "NotNone"
|
||||
assert checkString(True, "NotNone",False) == "NotNone"
|
||||
|
||||
@pytest.mark.core
|
||||
def testCheckInt():
|
||||
assert checkInt(None, 3,True) is None
|
||||
assert checkInt("None",3,True) is None
|
||||
@@ -23,6 +25,7 @@ def testCheckInt():
|
||||
assert checkInt(1.0, 3,False) == 1
|
||||
assert checkInt(True, 3,False) == 1
|
||||
|
||||
@pytest.mark.core
|
||||
def testCheckBool():
|
||||
assert checkBool(None, 3, True) is None
|
||||
assert checkBool("None", 3, True) is None
|
||||
@@ -36,6 +39,7 @@ def testCheckBool():
|
||||
assert checkBool(1.0, None, False) is None
|
||||
assert checkBool(2.0, None, False) is None
|
||||
|
||||
@pytest.mark.core
|
||||
def testColRange():
|
||||
assert colRange([0,0], [0,0], 0) is None
|
||||
assert cmpList(colRange([200,50,0], [50,200,0], 1), [200,50,0])
|
||||
|
||||
+48
-1
@@ -2,7 +2,7 @@
|
||||
"""novelWriter Config Class Tester
|
||||
"""
|
||||
|
||||
import nw
|
||||
import nw, pytest
|
||||
from nwtools import *
|
||||
from os import path, unlink
|
||||
from nw.config import Config
|
||||
@@ -20,10 +20,57 @@ ensureDir(testTemp)
|
||||
if path.isfile(tmpConf):
|
||||
unlink(tmpConf)
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigInit():
|
||||
assert theConf.initConfig(testTemp)
|
||||
assert cmpFiles(tmpConf, refConf, [2])
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigSave():
|
||||
assert theConf.saveConfig()
|
||||
assert cmpFiles(tmpConf, refConf, [2])
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigSetConfPath():
|
||||
assert theConf.setConfPath(None)
|
||||
assert not theConf.setConfPath(path.join("somewhere","over","the","rainbow"))
|
||||
assert theConf.setConfPath(path.join(testTemp,"novelwriter.conf"))
|
||||
assert theConf.confPath == testTemp
|
||||
assert theConf.confFile == "novelwriter.conf"
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigLoad():
|
||||
assert theConf.loadConfig()
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigSetWinSize():
|
||||
assert theConf.setWinSize(1105, 655)
|
||||
assert not theConf.confChanged
|
||||
assert theConf.setWinSize(70,70)
|
||||
assert theConf.confChanged
|
||||
assert theConf.setWinSize(1100, 650)
|
||||
assert theConf.saveConfig()
|
||||
assert cmpFiles(tmpConf, refConf, [2])
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigSetTreeColWidths():
|
||||
assert theConf.setTreeColWidths([0, 0, 0])
|
||||
assert theConf.confChanged
|
||||
assert theConf.setTreeColWidths([120, 30, 50])
|
||||
assert theConf.saveConfig()
|
||||
assert cmpFiles(tmpConf, refConf, [2])
|
||||
assert not theConf.confChanged
|
||||
|
||||
@pytest.mark.core
|
||||
def testConfigSetMainPanePos():
|
||||
assert theConf.setMainPanePos([0, 0])
|
||||
assert theConf.confChanged
|
||||
assert theConf.setMainPanePos([300, 800])
|
||||
assert theConf.saveConfig()
|
||||
assert cmpFiles(tmpConf, refConf, [2])
|
||||
assert not theConf.confChanged
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Main GUI Class Tester
|
||||
"""
|
||||
|
||||
import nw, pytest
|
||||
from nwtools import *
|
||||
from os import path, unlink
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
keyDelay = 10
|
||||
stepDelay = 50
|
||||
testDir = path.dirname(__file__)
|
||||
testRef = path.join(testDir,"reference")
|
||||
|
||||
@pytest.mark.gui
|
||||
def testMainWindows(qtbot, tmpdir):
|
||||
confDir = str(tmpdir.mkdir("conf"))
|
||||
projDir = str(tmpdir.mkdir("project"))
|
||||
nwGUI = nw.main(["--testmode","--config=%s" % confDir])
|
||||
qtbot.addWidget(nwGUI)
|
||||
nwGUI.show()
|
||||
qtbot.waitForWindowShown(nwGUI)
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Create new, save, open project
|
||||
nwGUI.theProject.handleSeed = 42
|
||||
assert nwGUI.theProject.setProjectPath(projDir)
|
||||
assert nwGUI.newProject()
|
||||
assert nwGUI.theProject.setProjectPath(projDir)
|
||||
assert nwGUI.saveProject()
|
||||
qtbot.wait(stepDelay)
|
||||
assert nwGUI.openProject(projDir)
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Check that tree items have been created
|
||||
assert nwGUI.treeView._getTreeItem("73475cb40a568") is not None
|
||||
assert nwGUI.treeView._getTreeItem("25fc0e7096fc6") is not None
|
||||
assert nwGUI.treeView._getTreeItem("31489056e0916") is not None
|
||||
assert nwGUI.treeView._getTreeItem("44cb730c42048") is not None
|
||||
assert nwGUI.treeView._getTreeItem("71ee45a3c0db9") is not None
|
||||
assert nwGUI.treeView._getTreeItem("811786ad1ae74") is not None
|
||||
|
||||
# Select the 'New Scene' file
|
||||
nwGUI.treeView.setFocus()
|
||||
nwGUI.treeView._getTreeItem("73475cb40a568").setExpanded(True)
|
||||
nwGUI.treeView._getTreeItem("25fc0e7096fc6").setExpanded(True)
|
||||
nwGUI.treeView._getTreeItem("31489056e0916").setSelected(True)
|
||||
assert nwGUI.openSelectedItem()
|
||||
|
||||
# Type something into the document
|
||||
nwGUI.docEditor.setFocus()
|
||||
for c in "# Hello World!":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "## With a Subtitle":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "### An Even Subier Title":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "#### Basically Not a Title at All":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "% How about a comment?":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
for c in "@keyword: value":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "This is a paragraph of dummy text.":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
for c in "This is another paragraph of much longer dummy text. It is in fact very very dumb dummy text! ":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
for c in "We can also try replacing \"quotes\", even single's quotes are replaced. ":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
for c in "We can hyphen-ate, make dashes -- and even longer dashes --- if we want. ":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
for c in "Ellipsis? Not a problem either ... ":
|
||||
qtbot.keyClick(nwGUI.docEditor, c, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
|
||||
|
||||
qtbot.wait(stepDelay)
|
||||
nwGUI.docEditor._runCounter()
|
||||
qtbot.wait(1000)
|
||||
|
||||
# Save the document
|
||||
assert nwGUI.docEditor.docChanged
|
||||
assert nwGUI.saveDocument()
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Check the files
|
||||
projFile = path.join(projDir,"nwProject.nwx")
|
||||
assert cmpFiles(projFile, path.join(testRef,"gui_nwProject.nwx"), [2])
|
||||
sceneFile = path.join(projDir,"data_3","1489056e0916_main.nwd")
|
||||
assert cmpFiles(sceneFile, path.join(testRef,"gui_1489056e0916_main.nwd"))
|
||||
|
||||
# qtbot.stopForInteraction()
|
||||
@@ -2,8 +2,7 @@
|
||||
"""novelWriter Project Class Tester
|
||||
"""
|
||||
|
||||
import nw
|
||||
import types
|
||||
import nw, pytest, types
|
||||
from os import path, unlink
|
||||
|
||||
from nwtools import *
|
||||
@@ -31,20 +30,24 @@ theProject.handleSeed = 42
|
||||
|
||||
projFile = path.join(testProj,"nwProject.nwx")
|
||||
|
||||
@pytest.mark.project
|
||||
def testProjectNew():
|
||||
assert theProject.newProject()
|
||||
assert theProject.setProjectPath(testProj)
|
||||
assert theProject.saveProject()
|
||||
assert cmpFiles(projFile, path.join(testRef,"new_nwProject.nwx"), [2])
|
||||
|
||||
@pytest.mark.project
|
||||
def testProjectOpen():
|
||||
assert theProject.openProject(projFile)
|
||||
|
||||
@pytest.mark.project
|
||||
def testProjectSave():
|
||||
assert theProject.saveProject()
|
||||
assert cmpFiles(projFile, path.join(testRef,"new_nwProject.nwx"), [2])
|
||||
assert not theProject.projChanged
|
||||
|
||||
@pytest.mark.project
|
||||
def testProjectNewRoot():
|
||||
assert theProject.openProject(projFile)
|
||||
assert isinstance(theProject.newRoot("Novel", nwItemClass.NOVEL), type(None))
|
||||
|
||||
Reference in New Issue
Block a user