Move tools source files to their own folder

This commit is contained in:
Veronica K. B. Olsen
2021-04-23 21:34:45 +02:00
parent 1c072e9f32
commit 03a80beebe
14 changed files with 553 additions and 549 deletions
+254
View File
@@ -0,0 +1,254 @@
# -*- coding: utf-8 -*-
"""
novelWriter Build Dialog Class Tester
=======================================
This file is a part of novelWriter
Copyright 20182021, 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 <https://www.gnu.org/licenses/>.
"""
import pytest
import os
from shutil import copyfile
from tools import cmpFiles, getGuiItem
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAction, QMessageBox, QFileDialog
from nw.tools import GuiBuildNovel
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testToolBuild_Main(qtbot, monkeypatch, nwGUI, nwLipsum, refDir, outDir):
"""Test the build tool.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "information", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda a, b, c, **kwargs: (c, None))
# Check that we cannot open when there is no project
nwGUI.mainMenu.aBuildProject.activate(QAction.Trigger)
assert getGuiItem("GuiBuildNovel") is None
# Open a project
assert nwGUI.openProject(nwLipsum)
nwGUI.mainConf.lastPath = nwLipsum
# Open the tool
nwGUI.mainMenu.aBuildProject.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiBuildNovel") is not None, timeout=1000)
nwBuild = getGuiItem("GuiBuildNovel")
assert isinstance(nwBuild, GuiBuildNovel)
nwBuild.textFont.setText("DejaVu Sans")
nwBuild.textSize.setValue(11)
# Default Settings
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)
assert nwBuild._saveDocument(nwBuild.FMT_NWD)
assert nwBuild._saveDocument(nwBuild.FMT_HTM)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.nwd")
testFile = os.path.join(outDir, "guiBuild_Tool_Step1_Lorem_Ipsum.nwd")
compFile = os.path.join(refDir, "guiBuild_Tool_Step1_Lorem_Ipsum.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.htm")
testFile = os.path.join(outDir, "guiBuild_Tool_Step1_Lorem_Ipsum.htm")
compFile = os.path.join(refDir, "guiBuild_Tool_Step1_Lorem_Ipsum.htm")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_MD)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.md")
testFile = os.path.join(outDir, "guiBuild_Tool_Step1_Lorem_Ipsum.md")
compFile = os.path.join(refDir, "guiBuild_Tool_Step1_Lorem_Ipsum.md")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_GH)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.md")
testFile = os.path.join(outDir, "guiBuild_Tool_Step1G_Lorem_Ipsum.md")
compFile = os.path.join(refDir, "guiBuild_Tool_Step1G_Lorem_Ipsum.md")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Change Title Formats and Flip Switches
nwBuild.fmtChapter.setText(r"Chapter %chw%: %title%")
qtbot.wait(stepDelay)
nwBuild.fmtScene.setText(r"Scene %ch%.%sc%: %title%")
qtbot.wait(stepDelay)
nwBuild.fmtSection.setText(r"%ch%.%sc%.1: %title%")
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.justifyText, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeSynopsis, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeComments, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeKeywords, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.replaceUCode, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.noteFiles, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.ignoreFlag, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)
assert nwBuild._saveDocument(nwBuild.FMT_NWD)
assert nwBuild._saveDocument(nwBuild.FMT_HTM)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.nwd")
testFile = os.path.join(outDir, "guiBuild_Tool_Step2_Lorem_Ipsum.nwd")
compFile = os.path.join(refDir, "guiBuild_Tool_Step2_Lorem_Ipsum.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.htm")
testFile = os.path.join(outDir, "guiBuild_Tool_Step2_Lorem_Ipsum.htm")
compFile = os.path.join(refDir, "guiBuild_Tool_Step2_Lorem_Ipsum.htm")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_MD)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.md")
testFile = os.path.join(outDir, "guiBuild_Tool_Step2_Lorem_Ipsum.md")
compFile = os.path.join(refDir, "guiBuild_Tool_Step2_Lorem_Ipsum.md")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Replace Tabs with Spaces
qtbot.mouseClick(nwBuild.replaceTabs, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)
# Save files that can be compared
assert nwBuild._saveDocument(nwBuild.FMT_NWD)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.nwd")
testFile = os.path.join(outDir, "guiBuild_Tool_Step3_Lorem_Ipsum.nwd")
compFile = os.path.join(refDir, "guiBuild_Tool_Step3_Lorem_Ipsum.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_HTM)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.htm")
testFile = os.path.join(outDir, "guiBuild_Tool_Step3_Lorem_Ipsum.htm")
compFile = os.path.join(refDir, "guiBuild_Tool_Step3_Lorem_Ipsum.htm")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_MD)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.md")
testFile = os.path.join(outDir, "guiBuild_Tool_Step3_Lorem_Ipsum.md")
compFile = os.path.join(refDir, "guiBuild_Tool_Step3_Lorem_Ipsum.md")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Putline Mode
nwBuild.fmtChapter.setText(r"Chapter %chw%: %title%")
qtbot.wait(stepDelay)
nwBuild.fmtScene.setText(r"Scene %sca%: %title%")
qtbot.wait(stepDelay)
nwBuild.fmtSection.setText(r"Section: %title%")
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeComments, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.noteFiles, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.ignoreFlag, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.includeBody, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)
# Save files that can be compared
assert nwBuild._saveDocument(nwBuild.FMT_NWD)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.nwd")
testFile = os.path.join(outDir, "guiBuild_Tool_Step4_Lorem_Ipsum.nwd")
compFile = os.path.join(refDir, "guiBuild_Tool_Step4_Lorem_Ipsum.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
assert nwBuild._saveDocument(nwBuild.FMT_HTM)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.htm")
testFile = os.path.join(outDir, "guiBuild_Tool_Step4_Lorem_Ipsum.htm")
compFile = os.path.join(refDir, "guiBuild_Tool_Step4_Lorem_Ipsum.htm")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Check the JSON files too at this stage
assert nwBuild._saveDocument(nwBuild.FMT_JSON_H)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.json")
testFile = os.path.join(outDir, "guiBuild_Tool_Step4H_Lorem_Ipsum.json")
compFile = os.path.join(refDir, "guiBuild_Tool_Step4H_Lorem_Ipsum.json")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, [8])
assert nwBuild._saveDocument(nwBuild.FMT_JSON_M)
projFile = os.path.join(nwLipsum, "Lorem Ipsum.json")
testFile = os.path.join(outDir, "guiBuild_Tool_Step4M_Lorem_Ipsum.json")
compFile = os.path.join(refDir, "guiBuild_Tool_Step4M_Lorem_Ipsum.json")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, [8])
# Save other file types handled by Qt
# We assume the export itself by the Qt library works, so we just
# check that novelWriter successfully writes the files.
assert nwBuild._saveDocument(nwBuild.FMT_ODT)
assert os.path.isfile(os.path.join(nwLipsum, "Lorem Ipsum.odt"))
if not nwGUI.mainConf.osDarwin:
assert nwBuild._saveDocument(nwBuild.FMT_PDF)
assert os.path.isfile(os.path.join(nwLipsum, "Lorem Ipsum.pdf"))
# Close the build tool
htmlText = nwBuild.htmlText
htmlStyle = nwBuild.htmlStyle
buildTime = nwBuild.buildTime
nwBuild._doClose()
# Re-open build dialog from cahce
nwGUI.mainMenu.aBuildProject.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiBuildNovel") is not None, timeout=1000)
nwBuild = getGuiItem("GuiBuildNovel")
assert isinstance(nwBuild, GuiBuildNovel)
assert nwBuild.viewCachedDoc()
assert nwBuild.htmlText == htmlText
assert nwBuild.htmlStyle == htmlStyle
assert nwBuild.buildTime == buildTime
nwBuild._doClose()
# qtbot.stopForInteraction()
# END Test testToolBuild_Main
+229
View File
@@ -0,0 +1,229 @@
# -*- coding: utf-8 -*-
"""
novelWriter New Project Wizard Class Tester
=============================================
This file is a part of novelWriter
Copyright 20182021, 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 <https://www.gnu.org/licenses/>.
"""
import pytest
import os
import sys
from tools import getGuiItem
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QFileDialog, QWizard, QMessageBox
from nw.enum import nwItemClass
from nw.tools.projwizard import (
GuiProjectWizard, ProjWizardIntroPage, ProjWizardFolderPage,
ProjWizardPopulatePage, ProjWizardCustomPage, ProjWizardFinalPage
)
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testToolProjectWizard_Main(qtbot, monkeypatch, nwGUI, nwMinimal):
"""Test the new project wizard.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *args: QMessageBox.Yes)
if sys.platform.startswith("darwin"):
# Disable for macOS because the test segfaults on QWizard.show()
return
##
# Test New Project Function
##
# New with a project open should cause an error
assert nwGUI.openProject(nwMinimal)
assert not nwGUI.newProject()
# Close project, but call with invalid path
assert nwGUI.closeProject()
with monkeypatch.context() as mp:
mp.setattr(nwGUI, "showNewProjectDialog", lambda *args: None)
assert not nwGUI.newProject()
# Now, with an empty dictionary
mp.setattr(nwGUI, "showNewProjectDialog", lambda *args: {})
assert not nwGUI.newProject()
# Now, with a non-empty folder
mp.setattr(nwGUI, "showNewProjectDialog", lambda *args: {"projPath": nwMinimal})
assert not nwGUI.newProject()
##
# Test the Wizard
##
monkeypatch.setattr(GuiProjectWizard, "exec_", lambda *args: None)
nwGUI.mainConf.lastPath = " "
nwGUI.closeProject()
nwGUI.showNewProjectDialog()
qtbot.waitUntil(lambda: getGuiItem("GuiProjectWizard") is not None, timeout=1000)
nwWiz = getGuiItem("GuiProjectWizard")
assert isinstance(nwWiz, GuiProjectWizard)
nwWiz.show()
qtbot.wait(stepDelay)
for wStep in range(4):
# This does not actually create the project, it just generates the
# dictionary that defines it.
# Intro Page
introPage = nwWiz.currentPage()
assert isinstance(introPage, ProjWizardIntroPage)
assert not nwWiz.button(QWizard.NextButton).isEnabled()
qtbot.wait(stepDelay)
for c in ("Test Minimal %d" % wStep):
qtbot.keyClick(introPage.projName, c, delay=typeDelay)
qtbot.wait(stepDelay)
for c in "Minimal Novel":
qtbot.keyClick(introPage.projTitle, c, delay=typeDelay)
qtbot.wait(stepDelay)
for c in "Jane Doe":
qtbot.keyClick(introPage.projAuthors, c, delay=typeDelay)
# Setting projName should activate the button
assert nwWiz.button(QWizard.NextButton).isEnabled()
qtbot.wait(stepDelay)
qtbot.mouseClick(nwWiz.button(QWizard.NextButton), Qt.LeftButton)
# Folder Page
storagePage = nwWiz.currentPage()
assert isinstance(storagePage, ProjWizardFolderPage)
assert not nwWiz.button(QWizard.NextButton).isEnabled()
if wStep == 0:
# Check invalid path first, the first time we reach here
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *a, **kw: "")
qtbot.wait(stepDelay)
qtbot.mouseClick(storagePage.browseButton, Qt.LeftButton, delay=100)
assert storagePage.projPath.text() == ""
# Then, we always return nwMinimal as path
monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *a, **kw: nwMinimal)
qtbot.wait(stepDelay)
qtbot.mouseClick(storagePage.browseButton, Qt.LeftButton, delay=100)
projPath = os.path.join(nwMinimal, "Test Minimal %d" % wStep)
assert storagePage.projPath.text() == projPath
# Setting projPath should activate the button
assert nwWiz.button(QWizard.NextButton).isEnabled()
qtbot.wait(stepDelay)
qtbot.mouseClick(nwWiz.button(QWizard.NextButton), Qt.LeftButton)
# Populate Page
popPage = nwWiz.currentPage()
assert isinstance(popPage, ProjWizardPopulatePage)
assert nwWiz.button(QWizard.NextButton).isEnabled()
qtbot.wait(stepDelay)
if wStep == 0:
popPage.popMinimal.setChecked(True)
elif wStep == 1:
popPage.popCustom.setChecked(True)
elif wStep == 2:
popPage.popCustom.setChecked(True)
elif wStep == 3:
popPage.popSample.setChecked(True)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwWiz.button(QWizard.NextButton), Qt.LeftButton)
# Custom Page
if wStep == 1 or wStep == 2:
customPage = nwWiz.currentPage()
assert isinstance(customPage, ProjWizardCustomPage)
assert nwWiz.button(QWizard.NextButton).isEnabled()
customPage.addPlot.setChecked(True)
customPage.addChar.setChecked(True)
customPage.addWorld.setChecked(True)
customPage.addTime.setChecked(True)
customPage.addObject.setChecked(True)
customPage.addEntity.setChecked(True)
if wStep == 2:
customPage.numChapters.setValue(0)
customPage.numScenes.setValue(10)
customPage.chFolders.setChecked(False)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwWiz.button(QWizard.NextButton), Qt.LeftButton)
# Final Page
finalPage = nwWiz.currentPage()
assert isinstance(finalPage, ProjWizardFinalPage)
assert nwWiz.button(QWizard.FinishButton).isEnabled() # But we don't click it
# Check Data
projData = nwGUI._assembleProjectWizardData(nwWiz)
assert projData["projName"] == "Test Minimal %d" % wStep
assert projData["projTitle"] == "Minimal Novel"
assert projData["projAuthors"] == "Jane Doe"
assert projData["projPath"] == projPath
assert projData["popMinimal"] == (wStep == 0)
assert projData["popCustom"] == (wStep == 1 or wStep == 2)
assert projData["popSample"] == (wStep == 3)
if wStep == 1 or wStep == 2:
assert projData["addRoots"] == [
nwItemClass.PLOT,
nwItemClass.CHARACTER,
nwItemClass.WORLD,
nwItemClass.TIMELINE,
nwItemClass.OBJECT,
nwItemClass.ENTITY,
]
if wStep == 1:
assert projData["numChapters"] == 5
assert projData["numScenes"] == 5
assert projData["chFolders"]
else:
assert projData["numChapters"] == 0
assert projData["numScenes"] == 10
assert not projData["chFolders"]
else:
assert projData["addRoots"] == []
assert projData["numChapters"] == 0
assert projData["numScenes"] == 0
assert not projData["chFolders"]
# Restart the wizard for next iteration
nwWiz.restart()
nwWiz.reject()
nwWiz.close()
# qtbot.stopForInteraction()
# END Test testToolProjectWizard_Main
+431
View File
@@ -0,0 +1,431 @@
# -*- coding: utf-8 -*-
"""
novelWriter Writing Stats Dialog Class Tester
===============================================
This file is a part of novelWriter
Copyright 20182021, 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 <https://www.gnu.org/licenses/>.
"""
import pytest
import json
import os
from tools import getGuiItem, writeFile
from dummy import causeOSError
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox
from nw.tools import GuiWritingStats
from nw.constants import nwFiles
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj):
"""Test the full writing stats tool.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "information", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "warning", lambda *args: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *args: QMessageBox.Yes)
# Create a project to work on
assert nwGUI.newProject({"projPath": fncProj})
qtbot.wait(100)
assert nwGUI.saveProject()
sessFile = os.path.join(fncProj, "meta", nwFiles.SESS_STATS)
# Open the Writing Stats dialog
nwGUI.mainConf.lastPath = ""
nwGUI.mainMenu.aWritingStats.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiWritingStats") is not None, timeout=1000)
sessLog = getGuiItem("GuiWritingStats")
assert isinstance(sessLog, GuiWritingStats)
qtbot.wait(stepDelay)
# Test Loading
# ============
# No initial logfile
assert not os.path.isfile(sessFile)
assert not sessLog._loadLogFile()
# Make a test log file
writeFile(sessFile, (
"# Offset 123\n"
"# Start Time End Time Novel Notes Idle\n"
"2020-01-01 21:00:00 2020-01-01 21:00:05 6 0\n"
"2020-01-03 21:00:00 2020-01-03 21:00:15 125 0\n"
"2020-01-03 21:30:00 2020-01-03 21:30:15 125 5\n"
"2020-01-06 21:00:00 2020-01-06 21:00:10 125 5\n"
))
assert os.path.isfile(sessFile)
assert sessLog._loadLogFile()
assert sessLog.wordOffset == 123
assert len(sessLog.logData) == 4
# Make sure a faulty file can still be read
writeFile(sessFile, (
"# Offset abc123\n"
"# Start Time End Time Novel Notes Idle\n"
"2020-01-01 21:00:00 2020-01-01 21:00:05 6 0 50\n"
"2020-01-03 21:00:00 2020-01-03 21:00:15 125 0\n"
"2020-01-03 21:30:00 2020-01-03 21:30:15 125 5\n"
"2020-01-06 21:00:00 2020-01-06 21:00:10 125\n"
))
assert sessLog._loadLogFile()
assert sessLog.wordOffset == 0
assert len(sessLog.logData) == 3
# Test Exporting
# ==============
writeFile(sessFile, (
"# Offset 1075\n"
"# Start Time End Time Novel Notes Idle\n"
"2021-01-31 19:00:00 2021-01-31 19:30:00 700 375 0\n"
"2021-02-01 19:00:00 2021-02-01 19:30:00 700 375 10\n"
"2021-02-01 20:00:00 2021-02-01 20:30:00 600 275 20\n"
"2021-02-02 19:00:00 2021-02-02 19:30:00 750 425 30\n"
"2021-02-02 20:00:00 2021-02-02 20:30:00 690 365 40\n"
"2021-02-03 19:00:00 2021-02-03 19:30:00 680 355 50\n"
"2021-02-04 19:00:00 2021-02-04 19:30:00 700 375 60\n"
"2021-02-05 19:00:00 2021-02-05 19:30:00 500 175 70\n"
"2021-02-06 19:00:00 2021-02-06 19:30:00 600 275 80\n"
"2021-02-07 19:00:00 2021-02-07 19:30:00 600 275 90\n"
))
sessLog.populateGUI()
# Make the saving fail
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda *args, **kwargs: ("", ""))
assert not sessLog._saveData(sessLog.FMT_CSV)
assert not sessLog._saveData(sessLog.FMT_JSON)
assert not sessLog._saveData(None)
# Make the save succeed
monkeypatch.setattr("os.path.expanduser", lambda *args: fncDir)
monkeypatch.setattr(QFileDialog, "getSaveFileName", lambda ss, tt, pp, options: (pp, ""))
sessLog.listBox.sortByColumn(sessLog.C_TIME, 0)
assert sessLog.novelWords.text() == "{:n}".format(600)
assert sessLog.notesWords.text() == "{:n}".format(275)
assert sessLog.totalWords.text() == "{:n}".format(875)
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(-200)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(300)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(-120)
assert sessLog.listBox.topLevelItem(4).text(sessLog.C_COUNT) == "{:n}".format(-20)
assert sessLog.listBox.topLevelItem(5).text(sessLog.C_COUNT) == "{:n}".format(40)
assert sessLog.listBox.topLevelItem(6).text(sessLog.C_COUNT) == "{:n}".format(-400)
assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(200)
assert sessLog._saveData(sessLog.FMT_CSV)
qtbot.wait(100)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(100)
assert nwGUI.mainConf.lastPath == fncDir
# Check the exported files
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.load(inFile)
assert jsonData == [
{
"date": "2021-01-31 19:00:00", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-01 20:00:00", "length": 1800.0,
"newWords": -200, "novelWords": 600, "noteWords": 275, "idleTime": 20
}, {
"date": "2021-02-02 19:00:00", "length": 1800.0,
"newWords": 300, "novelWords": 750, "noteWords": 425, "idleTime": 30
}, {
"date": "2021-02-02 20:00:00", "length": 1800.0,
"newWords": -120, "novelWords": 690, "noteWords": 365, "idleTime": 40
}, {
"date": "2021-02-03 19:00:00", "length": 1800.0,
"newWords": -20, "novelWords": 680, "noteWords": 355, "idleTime": 50
}, {
"date": "2021-02-04 19:00:00", "length": 1800.0,
"newWords": 40, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-05 19:00:00", "length": 1800.0,
"newWords": -400, "novelWords": 500, "noteWords": 175, "idleTime": 70
}, {
"date": "2021-02-06 19:00:00", "length": 1800.0,
"newWords": 200, "novelWords": 600, "noteWords": 275, "idleTime": 80
}
]
# Test Filters
# ============
# No Novel Files
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
qtbot.wait(stepDelay)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(stepDelay)
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.loads(inFile.read())
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(-100)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(150)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(-60)
assert sessLog.listBox.topLevelItem(4).text(sessLog.C_COUNT) == "{:n}".format(-10)
assert sessLog.listBox.topLevelItem(5).text(sessLog.C_COUNT) == "{:n}".format(20)
assert sessLog.listBox.topLevelItem(6).text(sessLog.C_COUNT) == "{:n}".format(-200)
assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(100)
assert jsonData == [
{
"date": "2021-01-31 19:00:00", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-01 20:00:00", "length": 1800.0,
"newWords": -100, "novelWords": 600, "noteWords": 275, "idleTime": 20
}, {
"date": "2021-02-02 19:00:00", "length": 1800.0,
"newWords": 150, "novelWords": 750, "noteWords": 425, "idleTime": 30
}, {
"date": "2021-02-02 20:00:00", "length": 1800.0,
"newWords": -60, "novelWords": 690, "noteWords": 365, "idleTime": 40
}, {
"date": "2021-02-03 19:00:00", "length": 1800.0,
"newWords": -10, "novelWords": 680, "noteWords": 355, "idleTime": 50
}, {
"date": "2021-02-04 19:00:00", "length": 1800.0,
"newWords": 20, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-05 19:00:00", "length": 1800.0,
"newWords": -200, "novelWords": 500, "noteWords": 175, "idleTime": 70
}, {
"date": "2021-02-06 19:00:00", "length": 1800.0,
"newWords": 100, "novelWords": 600, "noteWords": 275, "idleTime": 80
}
]
# No Note Files
qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton)
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
qtbot.wait(stepDelay)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(stepDelay)
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.load(inFile)
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(-100)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(150)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(-60)
assert sessLog.listBox.topLevelItem(4).text(sessLog.C_COUNT) == "{:n}".format(-10)
assert sessLog.listBox.topLevelItem(5).text(sessLog.C_COUNT) == "{:n}".format(20)
assert sessLog.listBox.topLevelItem(6).text(sessLog.C_COUNT) == "{:n}".format(-200)
assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(100)
assert jsonData == [
{
"date": "2021-01-31 19:00:00", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-01 20:00:00", "length": 1800.0,
"newWords": -100, "novelWords": 600, "noteWords": 275, "idleTime": 20
}, {
"date": "2021-02-02 19:00:00", "length": 1800.0,
"newWords": 150, "novelWords": 750, "noteWords": 425, "idleTime": 30
}, {
"date": "2021-02-02 20:00:00", "length": 1800.0,
"newWords": -60, "novelWords": 690, "noteWords": 365, "idleTime": 40
}, {
"date": "2021-02-03 19:00:00", "length": 1800.0,
"newWords": -10, "novelWords": 680, "noteWords": 355, "idleTime": 50
}, {
"date": "2021-02-04 19:00:00", "length": 1800.0,
"newWords": 20, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-05 19:00:00", "length": 1800.0,
"newWords": -200, "novelWords": 500, "noteWords": 175, "idleTime": 70
}, {
"date": "2021-02-06 19:00:00", "length": 1800.0,
"newWords": 100, "novelWords": 600, "noteWords": 275, "idleTime": 80
}
]
# No Negative Entries
qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton)
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
qtbot.wait(stepDelay)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(stepDelay)
# qtbot.stopForInteraction()
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.load(inFile)
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(300)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(40)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(200)
assert jsonData == [
{
"date": "2021-01-31 19:00:00", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-02 19:00:00", "length": 1800.0,
"newWords": 300, "novelWords": 750, "noteWords": 425, "idleTime": 30
}, {
"date": "2021-02-04 19:00:00", "length": 1800.0,
"newWords": 40, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-06 19:00:00", "length": 1800.0,
"newWords": 200, "novelWords": 600, "noteWords": 275, "idleTime": 80
}
]
# Un-hide Zero Entries
qtbot.mouseClick(sessLog.hideNegative, Qt.LeftButton)
qtbot.mouseClick(sessLog.hideZeros, Qt.LeftButton)
qtbot.wait(stepDelay)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(stepDelay)
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.load(inFile)
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(0)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(-200)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(300)
assert sessLog.listBox.topLevelItem(4).text(sessLog.C_COUNT) == "{:n}".format(-120)
assert sessLog.listBox.topLevelItem(5).text(sessLog.C_COUNT) == "{:n}".format(-20)
assert sessLog.listBox.topLevelItem(6).text(sessLog.C_COUNT) == "{:n}".format(40)
assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(-400)
assert sessLog.listBox.topLevelItem(8).text(sessLog.C_COUNT) == "{:n}".format(200)
assert sessLog.listBox.topLevelItem(9).text(sessLog.C_COUNT) == "{:n}".format(0)
assert jsonData == [
{
"date": "2021-01-31 19:00:00", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-01 19:00:00", "length": 1800.0,
"newWords": 0, "novelWords": 700, "noteWords": 375, "idleTime": 10
}, {
"date": "2021-02-01 20:00:00", "length": 1800.0,
"newWords": -200, "novelWords": 600, "noteWords": 275, "idleTime": 20
}, {
"date": "2021-02-02 19:00:00", "length": 1800.0,
"newWords": 300, "novelWords": 750, "noteWords": 425, "idleTime": 30
}, {
"date": "2021-02-02 20:00:00", "length": 1800.0,
"newWords": -120, "novelWords": 690, "noteWords": 365, "idleTime": 40
}, {
"date": "2021-02-03 19:00:00", "length": 1800.0,
"newWords": -20, "novelWords": 680, "noteWords": 355, "idleTime": 50
}, {
"date": "2021-02-04 19:00:00", "length": 1800.0,
"newWords": 40, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-05 19:00:00", "length": 1800.0,
"newWords": -400, "novelWords": 500, "noteWords": 175, "idleTime": 70
}, {
"date": "2021-02-06 19:00:00", "length": 1800.0,
"newWords": 200, "novelWords": 600, "noteWords": 275, "idleTime": 80
}, {
"date": "2021-02-07 19:00:00", "length": 1800.0,
"newWords": 0, "novelWords": 600, "noteWords": 275, "idleTime": 90
}
]
# Group by Day
qtbot.mouseClick(sessLog.groupByDay, Qt.LeftButton)
qtbot.wait(stepDelay)
assert sessLog._saveData(sessLog.FMT_JSON)
qtbot.wait(stepDelay)
jsonStats = os.path.join(fncDir, "sessionStats.json")
with open(jsonStats, mode="r", encoding="utf-8") as inFile:
jsonData = json.load(inFile)
assert sessLog.listBox.topLevelItem(0).text(sessLog.C_COUNT) == "{:n}".format(1)
assert sessLog.listBox.topLevelItem(1).text(sessLog.C_COUNT) == "{:n}".format(-200)
assert sessLog.listBox.topLevelItem(2).text(sessLog.C_COUNT) == "{:n}".format(180)
assert sessLog.listBox.topLevelItem(3).text(sessLog.C_COUNT) == "{:n}".format(-20)
assert sessLog.listBox.topLevelItem(4).text(sessLog.C_COUNT) == "{:n}".format(40)
assert sessLog.listBox.topLevelItem(5).text(sessLog.C_COUNT) == "{:n}".format(-400)
assert sessLog.listBox.topLevelItem(6).text(sessLog.C_COUNT) == "{:n}".format(200)
assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(0)
assert jsonData == [
{
"date": "2021-01-31", "length": 1800.0,
"newWords": 1, "novelWords": 700, "noteWords": 375, "idleTime": 0
}, {
"date": "2021-02-01", "length": 3600.0,
"newWords": -200, "novelWords": 600, "noteWords": 275, "idleTime": 30
}, {
"date": "2021-02-02", "length": 3600.0,
"newWords": 180, "novelWords": 690, "noteWords": 365, "idleTime": 70
}, {
"date": "2021-02-03", "length": 1800.0,
"newWords": -20, "novelWords": 680, "noteWords": 355, "idleTime": 50
}, {
"date": "2021-02-04", "length": 1800.0,
"newWords": 40, "novelWords": 700, "noteWords": 375, "idleTime": 60
}, {
"date": "2021-02-05", "length": 1800.0,
"newWords": -400, "novelWords": 500, "noteWords": 175, "idleTime": 70
}, {
"date": "2021-02-06", "length": 1800.0,
"newWords": 200, "novelWords": 600, "noteWords": 275, "idleTime": 80
}, {
"date": "2021-02-07", "length": 1800.0,
"newWords": 0, "novelWords": 600, "noteWords": 275, "idleTime": 90
}
]
# IOError
# =======
monkeypatch.setattr("builtins.open", causeOSError)
assert not sessLog._loadLogFile()
assert not sessLog._saveData(sessLog.FMT_CSV)
# qtbot.stopForInteraction()
sessLog._doClose()
assert nwGUI.closeProject()
qtbot.wait(stepDelay)
# END Test testToolWritingStats_Main