Remove project meta attribute from project class
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user