diff --git a/.gitignore b/.gitignore index ff89acd8..cf07a362 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,12 @@ +# Python Temp __pycache__ -*.bak + +# Sample Project +sample/**/cache +sample/**/wordlist.txt +sample/**/*.bak + +# PyTest +tests/temp +.pytest_cache +pytestdebug.log diff --git a/nw/project/project.py b/nw/project/project.py index e03d9103..25a96609 100644 --- a/nw/project/project.py +++ b/nw/project/project.py @@ -33,6 +33,9 @@ class NWProject(): self.mainConf = self.theParent.mainConf self.projChanged = None + # Debug + self.handleSeed = None + # Project Settings self.projTree = None self.treeOrder = None @@ -56,6 +59,9 @@ class NWProject(): ## def newRoot(self, rootName, rootClass): + if not self.checkRootUnique(rootClass): + self.theParent.makeAlert("Duplicate root item detected!",2) + return None newItem = NWItem() newItem.setName(rootName) newItem.setType(nwItemType.ROOT) @@ -422,7 +428,12 @@ class NWProject(): return def _makeHandle(self, addSeed=""): - newSeed = str(time()) + addSeed + if self.handleSeed is None: + newSeed = str(time()) + addSeed + else: + # This is used for debugging + newSeed = str(self.handleSeed) + self.handleSeed += 1 logger.verbose("Generating handle with seed '%s'" % newSeed) itemHandle = sha256(newSeed.encode()).hexdigest()[0:13] if itemHandle in self.projTree.keys(): diff --git a/tests/nwdummy.py b/tests/nwdummy.py new file mode 100644 index 00000000..d033668e --- /dev/null +++ b/tests/nwdummy.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +"""novelWriter Test Dummy GUI Classes +""" + +class DummyMain(): + + def __init__(self): + self.mainConf = None + return + + def makeAlert(self, theMessage, theLevel): + if theLevel == 1: + lvlMsg = "WARNING: " + elif theLevel == 2: + lvlMsg = "ERROR: " + else: + lvlMsg = "" + if isinstance(theMessage, list): + for msgLine in logMsg: + print(lvlMsg+msgLine) + else: + print(lvlMsg+theMessage) + return + + def setStatus(self, theMessage): + return + + def setProjectStatus(self, isChanged): + return + +# END Class GuiMain diff --git a/tests/nwtools.py b/tests/nwtools.py index b689a50e..dc3bd24b 100644 --- a/tests/nwtools.py +++ b/tests/nwtools.py @@ -2,6 +2,13 @@ """novelWriter Test Tools """ +from os import path, mkdir + +def ensureDir(theDir): + if not path.isdir(theDir): + mkdir(theDir) + return + def cmpFiles(fileOne, fileTwo, ignoreLines=[]): foOne = open(fileOne,mode="r") foTwo = open(fileTwo,mode="r") diff --git a/tests/reference/new_nwProject.nwx b/tests/reference/new_nwProject.nwx new file mode 100644 index 00000000..742afe41 --- /dev/null +++ b/tests/reference/new_nwProject.nwx @@ -0,0 +1,55 @@ + + + + + + + + + Novel + ROOT + NOVEL + 0 + False + + + Characters + ROOT + CHARACTER + 0 + False + + + Plot + ROOT + PLOT + 0 + False + + + World + ROOT + WORLD + 0 + False + + + New Chapter + FOLDER + NOVEL + 0 + False + + + New Scene + FILE + NOVEL + 0 + False + SCENE + 0 + 0 + 0 + + + diff --git a/tests/reference/roots_nwProject.nwx b/tests/reference/roots_nwProject.nwx new file mode 100644 index 00000000..1971370a --- /dev/null +++ b/tests/reference/roots_nwProject.nwx @@ -0,0 +1,83 @@ + + + + + + + + + Novel + ROOT + NOVEL + 0 + False + + + Characters + ROOT + CHARACTER + 0 + False + + + Plot + ROOT + PLOT + 0 + False + + + World + ROOT + WORLD + 0 + False + + + New Chapter + FOLDER + NOVEL + 0 + False + + + New Scene + FILE + NOVEL + 0 + False + SCENE + 0 + 0 + 0 + + + Timeline + ROOT + TIMELINE + 0 + False + + + Object + ROOT + OBJECT + 0 + False + + + Custom1 + ROOT + CUSTOM + 0 + False + + + Custom2 + ROOT + CUSTOM + 0 + False + + + diff --git a/tests/test_config.py b/tests/test_config.py index ce1c2ad2..90c68d8b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,18 +1,10 @@ # -*- coding: utf-8 -*- """novelWriter Config Class Tester - - novelWriter – Config Class Tester -=================================== - """ import nw -import filecmp - -from nwtools import cmpFiles - +from nwtools import * from os import path, unlink - from nw.config import Config theConf = Config() @@ -22,6 +14,8 @@ testRef = path.join(testDir,"reference") tmpConf = path.join(testTemp,"novelwriter.conf") refConf = path.join(testRef, "novelwriter.conf") +ensureDir(testTemp) + # Clean out old stuff if path.isfile(tmpConf): unlink(tmpConf) diff --git a/tests/test_project.py b/tests/test_project.py new file mode 100644 index 00000000..9aa0d2d1 --- /dev/null +++ b/tests/test_project.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +"""novelWriter Project Class Tester +""" + +import nw +import types +from os import path, unlink + +from nwtools import * +from nwdummy import DummyMain + +from nw.config import Config +from nw.project.project import NWProject +from nw.project.item import NWItem +from nw.enum import nwItemClass + +theConf = Config() +theMain = DummyMain() +theMain.mainConf = theConf +testDir = path.dirname(__file__) +testTemp = path.join(testDir,"temp") +testRef = path.join(testDir,"reference") +testProj = path.join(testTemp,"proj") + +ensureDir(testTemp) +ensureDir(testProj) + +theConf.initConfig(testRef) +theProject = NWProject(theMain) +theProject.handleSeed = 42 + +projFile = path.join(testProj,"nwProject.nwx") + +def testProjectNew(): + assert theProject.newProject() + assert theProject.setProjectPath(testProj) + assert theProject.saveProject() + assert cmpFiles(projFile, path.join(testRef,"new_nwProject.nwx"), [2]) + +def testProjectOpen(): + assert theProject.openProject(projFile) + +def testProjectSave(): + assert theProject.saveProject() + assert cmpFiles(projFile, path.join(testRef,"new_nwProject.nwx"), [2]) + assert not theProject.projChanged + +def testProjectNewRoot(): + assert theProject.openProject(projFile) + assert isinstance(theProject.newRoot("Novel", nwItemClass.NOVEL), type(None)) + assert isinstance(theProject.newRoot("Plot", nwItemClass.PLOT), type(None)) + assert isinstance(theProject.newRoot("Character", nwItemClass.CHARACTER), type(None)) + assert isinstance(theProject.newRoot("World", nwItemClass.WORLD), type(None)) + assert isinstance(theProject.newRoot("Timeline", nwItemClass.TIMELINE), str) + assert isinstance(theProject.newRoot("Object", nwItemClass.OBJECT), str) + assert isinstance(theProject.newRoot("Custom1", nwItemClass.CUSTOM), str) + assert isinstance(theProject.newRoot("Custom2", nwItemClass.CUSTOM), str) + assert theProject.projChanged + assert theProject.saveProject() + assert cmpFiles(projFile, path.join(testRef,"roots_nwProject.nwx"), [2]) + assert not theProject.projChanged