Remove project meta attribute from project class

This commit is contained in:
Veronica Berglyd Olsen
2022-11-05 23:29:25 +01:00
parent 82b34d9d2c
commit 21ab4e58f9
11 changed files with 117 additions and 159 deletions
+30 -16
View File
@@ -19,28 +19,30 @@ 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 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
+24 -56
View File
@@ -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"
-4
View File
@@ -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"]
+2 -2
View File
@@ -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")