diff --git a/novelwriter/core/sessions.py b/novelwriter/core/sessions.py index 3ed0e897..7fe3fd3a 100644 --- a/novelwriter/core/sessions.py +++ b/novelwriter/core/sessions.py @@ -112,7 +112,7 @@ class NWSessionLog: def iterRecords(self) -> Iterator[dict]: """Iterate through all records in the log.""" sessFile = self._project.storage.getMetaFile(nwFiles.SESS_FILE) - if isinstance(sessFile, Path): + if isinstance(sessFile, Path) and sessFile.is_file(): try: with open(sessFile, mode="r", encoding="utf-8") as fObj: for line in fObj: diff --git a/tests/test_core/test_core_sessions.py b/tests/test_core/test_core_sessions.py new file mode 100644 index 00000000..d7ee58f1 --- /dev/null +++ b/tests/test_core/test_core_sessions.py @@ -0,0 +1,114 @@ +""" +novelWriter – NWSessionLog Class Tester +======================================= + +This file is a part of novelWriter +Copyright 2018–2023, Veronica Berglyd Olsen + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +import pytest + +from time import sleep +from pathlib import Path + +from tools import buildTestProject +from mocked import causeOSError + +from novelwriter.constants import nwFiles +from novelwriter.core.project import NWProject +from novelwriter.core.sessions import NWSessionLog + + +@pytest.mark.core +def testCoreSessions_Main(monkeypatch, mockGUI, fncPath): + """Test log file handling of the NWSessionLog class.""" + project = NWProject(mockGUI) + buildTestProject(project, fncPath) + + logFile = project.storage.getMetaFile(nwFiles.SESS_FILE) + assert isinstance(logFile, Path) + + # Set some moch word counts + project.data.setInitCounts(50, 60) + project.data.setCurrCounts(160, 150) + + # The project init should already have created the session + sessLog = project.session + assert isinstance(sessLog, NWSessionLog) + assert sessLog.start > 0.0 + + # Starting the session again should reset the timer + currTime = sessLog.start + sleep(0.015) # Make sure we don't hit clock resolution issues on Windows + sessLog.startSession() + assert sessLog.start > currTime + + # There should not be a logfile + assert not logFile.exists() + assert len(list(sessLog.iterRecords())) == 0 + + # Create the initial and first records + assert sessLog.appendSession(0.8) is True + assert logFile.exists() # Logfile now exists + records = list(sessLog.iterRecords()) + assert len(records) == 2 + assert records[0]["type"] == "initial" + assert records[0]["offset"] == 110 # Sum of initial word counts + assert records[1]["type"] == "record" + assert records[1]["novel"] == 160 + assert records[1]["notes"] == 150 + assert records[1]["idle"] == 1 # Should be rounded to full seconds + + # Adding another record without changing word count should do nothing + project.data.setInitCounts(160, 150) + project.data.setCurrCounts(160, 150) + assert sessLog.appendSession(1.6) is False + assert len(list(sessLog.iterRecords())) == 2 + + # But adding when count has changed should + project.data.setInitCounts(160, 150) + project.data.setCurrCounts(270, 240) + sessLog._start -= 350.0 # Backdate the session start to allow logging + assert sessLog.appendSession(1.6) is True + records = list(sessLog.iterRecords()) + assert len(records) == 3 + assert records[2]["novel"] == 270 + assert records[2]["notes"] == 240 + assert records[2]["idle"] == 2 # Should be rounded to full seconds + + # Make file path unresolvable, and try appending another record + with monkeypatch.context() as mp: + mp.setattr("novelwriter.core.storage.NWStorage.getMetaFile", lambda *a: None) + assert sessLog.appendSession(1.6) is False + assert len(list(sessLog.iterRecords())) == 3 + + # Make the file open fail, and check that it's handled + with monkeypatch.context() as mp: + mp.setattr("builtins.open", causeOSError) + assert sessLog.appendSession(1.6) is False + assert len(list(sessLog.iterRecords())) == 3 + + # Make the file load fail, and check that it's handled + with monkeypatch.context() as mp: + mp.setattr("builtins.open", causeOSError) + assert len(list(sessLog.iterRecords())) == 0 + + # Make file path unresolvable + with monkeypatch.context() as mp: + mp.setattr("novelwriter.core.storage.NWStorage.getMetaFile", lambda *a: None) + assert len(list(sessLog.iterRecords())) == 0 + +# END Test testCoreSessions_Main