From 21ab4e58f9f30982ace2744d0550c50dd564a119 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 5 Nov 2022 23:29:25 +0100 Subject: [PATCH] Remove project meta attribute from project class --- novelwriter/core/coretools.py | 5 +- novelwriter/core/index.py | 14 +++-- novelwriter/core/options.py | 14 +++-- novelwriter/core/project.py | 53 ++---------------- novelwriter/core/storage.py | 27 +++++++--- novelwriter/dialogs/wordlist.py | 24 +++++---- novelwriter/tools/writingstats.py | 5 +- tests/test_core/test_core_options.py | 46 ++++++++++------ tests/test_core/test_core_project.py | 80 +++++++++------------------- tests/test_gui/test_gui_guimain.py | 4 -- tests/tools.py | 4 +- 11 files changed, 117 insertions(+), 159 deletions(-) diff --git a/novelwriter/core/coretools.py b/novelwriter/core/coretools.py index 1ff73d2e..f617817d 100644 --- a/novelwriter/core/coretools.py +++ b/novelwriter/core/coretools.py @@ -305,11 +305,10 @@ class ProjectBuilder: return False project = NWProject(self.mainGui) - if not project.setProjectPath(projPath, newProject=True): + if not project.storage.openProjectInPlace(projPath, newProject=True): return False - if not project.storage.openProjectInPlace(projPath): - return False + project.projPath = projPath lblNewProject = self.tr("New Project") lblNewChapter = self.tr("New Chapter") diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index ce1a1278..e7c50671 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -26,11 +26,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os import json import logging from time import time +from pathlib import Path from novelwriter.enum import nwItemType, nwItemLayout from novelwriter.error import logException @@ -141,12 +141,15 @@ class NWIndex: def loadIndex(self): """Load index from last session from the project meta folder. """ + indexFile = self.theProject.storage.getMetaFile(nwFiles.INDEX_FILE) + if not isinstance(indexFile, Path): + return False + theData = {} - indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE) tStart = time() self._indexBroken = False - if os.path.isfile(indexFile): + if indexFile.exists(): logger.debug("Loading index file") try: with open(indexFile, mode="r", encoding="utf-8") as inFile: @@ -184,8 +187,11 @@ class NWIndex: """Save the current index as a json file in the project meta data folder. """ + indexFile = self.theProject.storage.getMetaFile(nwFiles.INDEX_FILE) + if not isinstance(indexFile, Path): + return False + logger.debug("Saving index file") - indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE) tStart = time() try: diff --git a/novelwriter/core/options.py b/novelwriter/core/options.py index 9d840e0f..cbf3fe14 100644 --- a/novelwriter/core/options.py +++ b/novelwriter/core/options.py @@ -24,11 +24,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os import json import logging from enum import Enum +from pathlib import Path from novelwriter.error import logException from novelwriter.common import checkBool, checkFloat, checkInt, checkString @@ -77,13 +77,12 @@ class OptionState: def loadSettings(self): """Load the options dictionary from the project settings file. """ - if self.theProject.projMeta is None: + stateFile = self.theProject.storage.getMetaFile(nwFiles.OPTS_FILE) + if not isinstance(stateFile, Path): return False - stateFile = os.path.join(self.theProject.projMeta, nwFiles.OPTS_FILE) theState = {} - - if os.path.isfile(stateFile): + if stateFile.exists(): logger.debug("Loading GUI options file") try: with open(stateFile, mode="r", encoding="utf-8") as inFile: @@ -106,12 +105,11 @@ class OptionState: def saveSettings(self): """Save the options dictionary to the project settings file. """ - if self.theProject.projMeta is None: + stateFile = self.theProject.storage.getMetaFile(nwFiles.OPTS_FILE) + if not isinstance(stateFile, Path): return False - stateFile = os.path.join(self.theProject.projMeta, nwFiles.OPTS_FILE) logger.debug("Saving GUI options file") - try: with open(stateFile, mode="w+", encoding="utf-8") as outFile: json.dump(self._theState, outFile, indent=2) diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py index 9d0c78ca..891d8dde 100644 --- a/novelwriter/core/project.py +++ b/novelwriter/core/project.py @@ -27,6 +27,7 @@ from __future__ import annotations import os import json +from pathlib import Path import shutil import logging import novelwriter @@ -84,7 +85,6 @@ class NWProject(QObject): # Class Settings self.projPath = None # The full path to where the currently open project is saved - self.projMeta = None # The full path to the project's meta data folder self.projCache = None # The full path to the project's cache folder self.projContent = None # The full path to the project's content folder self.projDict = None # The spell check dictionary @@ -254,7 +254,6 @@ class NWProject(QObject): # Project Settings self.projPath = None - self.projMeta = None self.projCache = None self.projContent = None self.projDict = None @@ -276,11 +275,10 @@ class NWProject(QObject): self.projPath = str(self._storage.runtimePath) self.projContent = str(self._storage.contentPath) self.projCache = str(self._storage.cachePath) - self.projMeta = str(self._storage.metaPath) logger.info("Opening project: %s", self.projPath) - self.projDict = os.path.join(self.projMeta, nwFiles.PROJ_DICT) + self.projDict = str(self._storage.getMetaFile(nwFiles.PROJ_DICT)) # Project Lock # ============ @@ -421,8 +419,6 @@ class NWProject(QObject): return False saveTime = time() - if not self.ensureFolderStructure(): - return False logger.info("Saving project: %s", self.projPath) @@ -482,7 +478,6 @@ class NWProject(QObject): if self.projPath is None or self.projPath == "": return False - self.projMeta = os.path.join(self.projPath, "meta") self.projCache = os.path.join(self.projPath, "cache") self.projContent = os.path.join(self.projPath, "content") @@ -490,8 +485,6 @@ class NWProject(QObject): # Don't make a mess in the user's home folder return False - if not self._checkFolder(self.projMeta): - return False if not self._checkFolder(self.projCache): return False if not self._checkFolder(self.projContent): @@ -589,41 +582,6 @@ class NWProject(QObject): # Setters ## - def setProjectPath(self, projPath, newProject=False): - """Set the project storage path, and also expand ~ to the user - directory using the path library. - """ - if projPath is None or projPath == "": - self.projPath = None - else: - if projPath.startswith("~"): - projPath = os.path.expanduser(projPath) - self.projPath = os.path.abspath(projPath) - - if newProject: - if not os.path.isdir(projPath): - try: - os.mkdir(projPath) - logger.debug("Created folder: %s", projPath) - except Exception as exc: - self.mainGui.makeAlert(self.tr( - "Could not create new project folder." - ), nwAlert.ERROR, exception=exc) - return False - - if os.path.isdir(projPath): - if os.listdir(self.projPath): - self.mainGui.makeAlert(self.tr( - "New project folder is not empty. " - "Each project requires a dedicated project folder." - ), nwAlert.ERROR) - return False - - self.ensureFolderStructure() - self.setProjectChanged(True) - - return True - def setProjectLang(self, theLang): """Set the project-specific language. """ @@ -934,12 +892,10 @@ class NWProject(QObject): def _appendSessionStats(self, idleTime): """Append session statistics to the sessions log file. """ - if not self.ensureFolderStructure(): + sessionFile = self._storage.getMetaFile(nwFiles.SESS_STATS) + if not isinstance(sessionFile, Path): return False - sessionFile = os.path.join(self.projMeta, nwFiles.SESS_STATS) - isFile = os.path.isfile(sessionFile) - nowTime = time() iNovel, iNotes = self._data.initCounts cNovel, cNotes = self._data.currCounts @@ -953,6 +909,7 @@ class NWProject(QObject): return False try: + isFile = sessionFile.exists() # We must save the state before we open with open(sessionFile, mode="a+", encoding="utf-8") as outFile: if not isFile: # It's a new file, so add a header diff --git a/novelwriter/core/storage.py b/novelwriter/core/storage.py index 0813f7cc..485af8f0 100644 --- a/novelwriter/core/storage.py +++ b/novelwriter/core/storage.py @@ -97,7 +97,7 @@ class NWStorage: """ return self._runtimePath is not None - def openProjectInPlace(self, path): + def openProjectInPlace(self, path, newProject=False): """Open a novelWriter project in-place. That is, it is opened directly from a project folder. """ @@ -112,7 +112,7 @@ class NWStorage: self._lockFilePath = inPath / nwFiles.PROJ_LOCK self._openMode = self.MODE_INPLACE - if self._prepareStorage(checkLegacy=True) is False: + if not self._prepareStorage(checkLegacy=True, newProject=newProject): self.clear() return False @@ -142,7 +142,7 @@ class NWStorage: ## def getXmlReader(self): - """ + """Return a properly configured ProjectXMLReader instance. """ if self._runtimePath is None: return None @@ -153,7 +153,7 @@ class NWStorage: return xmlReader def getXmlWriter(self): - """ + """Return a properly configured ProjectXMLWriter instance. """ if self._runtimePath is None: return None @@ -165,8 +165,12 @@ class NWStorage: def getDocument(self, tHandle): pass - def getMetaFile(self, kind): - pass + def getMetaFile(self, fileName): + """Return the path to a file in the project meta folder. + """ + if self._runtimePath is not None: + return self._runtimePath / "meta" / fileName + return None def readLockFile(self): """Read the project lock file. @@ -234,7 +238,7 @@ class NWStorage: def _writeLockFile(self): pass - def _prepareStorage(self, checkLegacy=True): + def _prepareStorage(self, checkLegacy=True, newProject=False): """Prepare the storage area for the project. """ path = self._runtimePath @@ -248,6 +252,15 @@ class NWStorage: self.clear() return False + if newProject: + # If it's a new project, we check that there is no existing + # project in the selected path. + projFile = path / nwFiles.PROJ_FILE + if projFile.exists(): + logger.error("A project already exists in this path") + self.clear() + return False + # The folder is not required to exist, as it could be a new # project, so we make sure it does. Then we add subfolders. try: diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index 01a8afff..baabccdb 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -23,10 +23,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os import logging import novelwriter +from pathlib import Path + from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QListWidget, @@ -150,9 +151,11 @@ class GuiWordList(QDialog): """ self._saveGuiSettings() - dctFile = os.path.join(self.theProject.projMeta, nwFiles.PROJ_DICT) - tmpFile = dctFile + "~" + dctFile = self.theProject.storage.getMetaFile(nwFiles.PROJ_DICT) + if not isinstance(dctFile, Path): + return False + tmpFile = dctFile.with_suffix(".tmp") try: with open(tmpFile, mode="w", encoding="utf-8") as outFile: for i in range(self.listBox.count()): @@ -160,15 +163,16 @@ class GuiWordList(QDialog): if item is not None: outFile.write(item.text() + "\n") + if dctFile.exists(): + dctFile.unlink() + tmpFile.rename(dctFile) + except Exception: logger.error("Could not save new word list") logException() self.reject() return False - if os.path.isfile(dctFile): - os.unlink(dctFile) - os.rename(tmpFile, dctFile) self.accept() return True @@ -187,10 +191,12 @@ class GuiWordList(QDialog): def _loadWordList(self): """Load the project's word list, if it exists. """ - self.listBox.clear() + wordList = self.theProject.storage.getMetaFile(nwFiles.PROJ_DICT) + if not isinstance(wordList, Path): + return False - wordList = os.path.join(self.theProject.projMeta, nwFiles.PROJ_DICT) - if not os.path.isfile(wordList): + self.listBox.clear() + if not wordList.exists(): logger.debug("No project dictionary file found") return False diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 2a579837..7015c992 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -28,6 +28,7 @@ import json import logging import novelwriter +from pathlib import Path from datetime import datetime from PyQt5.QtGui import QPixmap, QCursor @@ -439,8 +440,8 @@ class GuiWritingStats(QDialog): ttTime = 0 ttIdle = 0 - logFile = os.path.join(self.theProject.projMeta, nwFiles.SESS_STATS) - if not os.path.isfile(logFile): + logFile = self.theProject.storage.getMetaFile(nwFiles.SESS_STATS) + if not isinstance(logFile, Path) or not logFile.exists(): logger.info("This project has no writing stats logfile") return False diff --git a/tests/test_core/test_core_options.py b/tests/test_core/test_core_options.py index 0535ca71..8d1b74fb 100644 --- a/tests/test_core/test_core_options.py +++ b/tests/test_core/test_core_options.py @@ -19,28 +19,30 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os import json import pytest from mock import causeOSError -from tools import writeFile +from novelwriter.constants import nwFiles from novelwriter.core.options import OptionState from novelwriter.core.project import NWProject -from novelwriter.constants import nwFiles +from novelwriter.gui.noveltree import NovelTreeColumn @pytest.mark.core -def testCoreOptions_LoadSave(monkeypatch, mockGUI, tmpDir): +def testCoreOptions_LoadSave(monkeypatch, mockGUI, fncPath): """Test loading and saving from the OptionState class. """ theProject = NWProject(mockGUI) theOpts = OptionState(theProject) + metaDir = fncPath / "meta" + metaDir.mkdir() + # Write a test file - optFile = os.path.join(tmpDir, nwFiles.OPTS_FILE) - writeFile(optFile, json.dumps({ + optFile = metaDir / nwFiles.OPTS_FILE + optFile.write_text(json.dumps({ "GuiBuildNovel": { "winWidth": 1000, "winHeight": 700, @@ -52,22 +54,22 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, tmpDir): "MockGroup": { "mockItem": None, }, - })) + }), encoding="utf-8") # Load and save with no path set - theProject.projMeta = None - assert not theOpts.loadSettings() - assert not theOpts.saveSettings() + theProject.storage._runtimePath = None + assert theOpts.loadSettings() is False + assert theOpts.saveSettings() is False # Set path - theProject.projMeta = tmpDir - assert theProject.projMeta == tmpDir + theProject.storage._runtimePath = fncPath + assert theProject.storage.getMetaFile(nwFiles.OPTS_FILE) == optFile # Cause open() to fail with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) - assert not theOpts.loadSettings() - assert not theOpts.saveSettings() + assert theOpts.loadSettings() is False + assert theOpts.saveSettings() is False # Load proper assert theOpts.loadSettings() @@ -108,9 +110,11 @@ def testCoreOptions_SetGet(mockGUI): theProject = NWProject(mockGUI) theOpts = OptionState(theProject) + nwColHidden = NovelTreeColumn.HIDDEN + # Set invalid values - assert not theOpts.setValue("MockGroup", "mockItem", None) - assert not theOpts.setValue("GuiBuildNovel", "mockItem", None) + assert theOpts.setValue("MockGroup", "mockItem", None) is False + assert theOpts.setValue("GuiBuildNovel", "mockItem", None) is False # Set valid value assert theOpts.setValue("GuiBuildNovel", "winWidth", 100) @@ -120,6 +124,7 @@ def testCoreOptions_SetGet(mockGUI): assert theOpts.setValue("GuiBuildNovel", "winHeight", 12.34) assert theOpts.setValue("GuiBuildNovel", "addNovel", True) assert theOpts.setValue("GuiBuildNovel", "textFont", "Cantarell") + assert theOpts.setValue("GuiNovelView", "lastCol", nwColHidden) # Generic get, doesn't check type assert theOpts.getValue("GuiBuildNovel", "winWidth", None) == 100 @@ -139,5 +144,14 @@ def testCoreOptions_SetGet(mockGUI): assert theOpts.getFloat("GuiBuildNovel", "mockItem", None) is None assert theOpts.getBool("GuiBuildNovel", "addNovel", None) is True assert theOpts.getBool("GuiBuildNovel", "mockItem", None) is None + assert theOpts.getEnum("GuiNovelView", "lastCol", NovelTreeColumn, None) == nwColHidden + + # Get from non-existent groups + assert theOpts.getValue("SomeGroup", "mockItem", None) is None + assert theOpts.getString("SomeGroup", "mockItem", None) is None + assert theOpts.getInt("SomeGroup", "mockItem", None) is None + assert theOpts.getFloat("SomeGroup", "mockItem", None) is None + assert theOpts.getBool("SomeGroup", "mockItem", None) is None + assert theOpts.getEnum("SomeGroup", "mockItem", NovelTreeColumn, None) is None # END Test testCoreOptions_SetGet diff --git a/tests/test_core/test_core_project.py b/tests/test_core/test_core_project.py index 752e216b..4404fdc3 100644 --- a/tests/test_core/test_core_project.py +++ b/tests/test_core/test_core_project.py @@ -23,11 +23,13 @@ import os import shutil import pytest +from time import time from shutil import copyfile +from pathlib import Path from zipfile import ZipFile from mock import causeOSError -from tools import C, cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE +from tools import C, cmpFiles, writeFile, buildTestProject, XML_IGNORE from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout from novelwriter.common import formatTimeStamp @@ -52,11 +54,6 @@ def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd): mockRnd.reset() buildTestProject(theProject, fncDir) - assert theProject.setProjectPath(fncDir) is True - assert theProject.saveProject() is True - assert theProject.closeProject() is True - assert theProject.openProject(projFile) is True - assert theProject.newRoot(nwItemClass.NOVEL) == "0000000000010" assert theProject.newRoot(nwItemClass.PLOT) == "0000000000011" assert theProject.newRoot(nwItemClass.CHARACTER) == "0000000000012" @@ -108,11 +105,6 @@ def testCoreProject_NewFileFolder(monkeypatch, fncDir, outDir, refDir, mockGUI, mockRnd.reset() buildTestProject(theProject, fncDir) - assert theProject.setProjectPath(fncDir) is True - assert theProject.saveProject() is True - assert theProject.closeProject() is True - assert theProject.openProject(projFile) is True - # Invalid call assert theProject.newFolder("New Folder", "1234567890abc") is None assert theProject.newFile("New File", "1234567890abc") is None @@ -195,7 +187,6 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncDir, mockRnd): assert theProject.openProject(fncDir) is False # Fail on lock file - theProject.setProjectPath(fncDir) assert theProject._storage.writeLockFile() assert theProject.openProject(fncDir) is False @@ -208,7 +199,6 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncDir, mockRnd): assert theProject.closeProject() # Force open with lockfile - theProject.setProjectPath(fncDir) assert theProject._storage.writeLockFile() assert theProject.openProject(fncDir, overrideLock=True) is True assert theProject.closeProject() @@ -267,12 +257,6 @@ def testCoreProject_Save(monkeypatch, mockGUI, mockRnd, fncDir, refDir): mockRnd.reset() buildTestProject(theProject, fncDir) - # Fail on folder structure check - with monkeypatch.context() as mp: - mp.setattr("os.mkdir", causeOSError) - shutil.rmtree(os.path.join(fncDir, "meta")) - assert theProject.saveProject() is False - # Fail writing with monkeypatch.context() as mp: mp.setattr(ProjectXMLWriter, "write", lambda *a: False) @@ -303,12 +287,6 @@ def testCoreProject_Helpers(monkeypatch, fncDir, mockGUI): mp.setattr("os.path.expanduser", lambda *a, **k: fncDir) assert theProject.ensureFolderStructure() is False - # Create a file to block meta folder - metaDir = os.path.join(fncDir, "meta") - writeFile(metaDir, "stuff") - assert theProject.ensureFolderStructure() is False - os.unlink(metaDir) - # Create a file to block cache folder cacheDir = os.path.join(fncDir, "cache") writeFile(cacheDir, "stuff") @@ -323,7 +301,7 @@ def testCoreProject_Helpers(monkeypatch, fncDir, mockGUI): # Now, do it right assert theProject.ensureFolderStructure() is True - assert os.path.isdir(metaDir) + # assert os.path.isdir(metaDir) assert os.path.isdir(cacheDir) assert os.path.isdir(contentDir) @@ -506,32 +484,12 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd): @pytest.mark.core -def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd): +def testCoreProject_Methods(monkeypatch, mockGUI, fncDir, mockRnd): """Test other project class methods and functions. """ theProject = NWProject(mockGUI) buildTestProject(theProject, fncDir) - # Setting project path - assert theProject.setProjectPath(None) - assert theProject.projPath is None - assert theProject.setProjectPath("") - assert theProject.projPath is None - assert theProject.setProjectPath("~") - assert theProject.projPath == os.path.expanduser("~") - - # Create a new folder and populate it - projPath = os.path.join(fncDir, "mock1") - assert theProject.setProjectPath(projPath, newProject=True) - - # Make os.mkdir fail - monkeypatch.setattr("os.mkdir", causeOSError) - projPath = os.path.join(fncDir, "mock2") - assert not theProject.setProjectPath(projPath, newProject=True) - - # Set back - assert theProject.setProjectPath(fncDir) - # Project Name theProject.data.setName(" A Name ") assert theProject.data.name == "A Name" @@ -639,29 +597,39 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd): assert theProject.tree.handles() == oldOrder # Session stats - theProject._data._initCounts = [50, 50] - theProject._data._currCounts = [100, 100] + theProject.data.setInitCounts(50, 50) + theProject.data.setCurrCounts(100, 100) + + # No path for writing with monkeypatch.context() as mp: - mp.setattr("os.path.isdir", lambda *a, **k: False) - assert not theProject._appendSessionStats(idleTime=0) + mp.setattr("novelwriter.core.storage.NWStorage.getMetaFile", lambda *a: None) + assert theProject._appendSessionStats(idleTime=0) is False # Block open with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) - assert not theProject._appendSessionStats(idleTime=0) + assert theProject._appendSessionStats(idleTime=0) is False + + # Session too short + theProject._projOpened = time() + theProject.data.setInitCounts(50, 50) + theProject.data.setCurrCounts(50, 50) + assert theProject._appendSessionStats(idleTime=0) is False # Write entry - assert theProject.projMeta == os.path.join(fncDir, "meta") - statsFile = os.path.join(theProject.projMeta, nwFiles.SESS_STATS) + statsFile = theProject.storage.getMetaFile(nwFiles.SESS_STATS) + assert isinstance(statsFile, Path) + statsFile.unlink(missing_ok=True) theProject._projOpened = 1600002000 - theProject._data._currCounts = [200, 100] + theProject.data._initCounts = [50, 50] + theProject.data._currCounts = [200, 100] with monkeypatch.context() as mp: mp.setattr("novelwriter.core.project.time", lambda: 1600005600) assert theProject._appendSessionStats(idleTime=99) - assert readFile(statsFile) == ( + assert statsFile.read_text(encoding="utf-8") == ( "# Offset 100\n" "# Start Time End Time Novel Notes Idle\n" "%s %s 200 100 99\n" diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index 28582695..4ec1ed5e 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -170,8 +170,6 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock assert len(nwGUI.theProject.tree._treeOrder) == 0 assert len(nwGUI.theProject.tree._treeRoots) == 0 assert nwGUI.theProject.tree.trashRoot() is None - assert nwGUI.theProject.projPath is None - assert nwGUI.theProject.projMeta is None assert nwGUI.theProject.data.name == "" assert nwGUI.theProject.data.title == "" assert nwGUI.theProject.data.authors == [] @@ -192,8 +190,6 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock assert len(nwGUI.theProject.tree._treeOrder) == 8 assert len(nwGUI.theProject.tree._treeRoots) == 4 assert nwGUI.theProject.tree.trashRoot() is None - assert nwGUI.theProject.projPath == fncProj - assert nwGUI.theProject.projMeta == os.path.join(fncProj, "meta") assert nwGUI.theProject.data.name == "New Project" assert nwGUI.theProject.data.title == "New Novel" assert nwGUI.theProject.data.authors == ["Jane Doe"] diff --git a/tests/tools.py b/tests/tools.py index e101bcbb..99f0d258 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -166,8 +166,8 @@ def buildTestProject(theObject, projPath): theProject = theObject.theProject theProject.clearProject() - theProject.setProjectPath(projPath, newProject=True) - theProject.storage.openProjectInPlace(theProject.projPath) + theProject.projPath = projPath + theProject.storage.openProjectInPlace(projPath) theProject.setDefaultStatusImport() theProject.data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")