Add test coverage of GUI theme

This commit is contained in:
Veronica Berglyd Olsen
2022-10-28 00:00:57 +02:00
parent 34193021e8
commit 28916afcce
2 changed files with 148 additions and 126 deletions
+1 -1
View File
@@ -247,7 +247,7 @@ class GuiTheme:
self.iconCache.updateTheme(self.themeIcons) self.iconCache.updateTheme(self.themeIcons)
# CSS File # CSS File
cssData = readTextFile(themeFile[:-5]+".css") cssData = readTextFile(themeFile[:-5]+".qss")
if cssData: if cssData:
qApp.setStyleSheet(cssData) qApp.setStyleSheet(cssData)
+147 -125
View File
@@ -19,157 +19,179 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import os
import shutil
import pytest import pytest
import novelwriter
from PyQt5.QtGui import QColor, QPixmap, QIcon from configparser import ConfigParser
from PyQt5.QtWidgets import QMessageBox
keyDelay = 2 from mock import causeOSError
typeDelay = 1 from tools import writeFile
stepDelay = 20
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QApplication, QMessageBox
from novelwriter.config import Config
from novelwriter.gui.theme import GuiTheme
@pytest.mark.gui @pytest.mark.gui
def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir): def testGuiTheme_Main(qtbot, monkeypatch, nwGUI, fncDir):
"""Test the theme and icon classes. """Test the theme class init.
""" """
# Block message box
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
nwGUI = novelwriter.main( mainTheme: GuiTheme = nwGUI.mainTheme
["--testmode", "--config=%s" % nwMinimal, "--data=%s" % tmpDir, nwMinimal] mainConf: Config = nwGUI.mainConf
)
qtbot.addWidget(nwGUI)
nwGUI.show()
qtbot.wait(stepDelay)
# Change Settings # Methods
assert novelwriter.CONFIG.confPath == nwMinimal # =======
novelwriter.CONFIG.guiTheme = "default_dark"
novelwriter.CONFIG.guiSyntax = "tomorrow_night_eighties"
novelwriter.CONFIG.guiFont = "Cantarell"
novelwriter.CONFIG.guiFontSize = 11
novelwriter.CONFIG.confChanged = True
assert novelwriter.CONFIG.saveConfig()
nwGUI.closeMain() mSize = mainTheme.getTextWidth("m")
nwGUI.close() assert mSize > 0
del nwGUI assert mainTheme.getTextWidth("m", mainTheme.guiFont) == mSize
# Re-open # Init Fonts
assert novelwriter.CONFIG.confPath == nwMinimal # ==========
nwGUI = novelwriter.main(
["--testmode", "--config=%s" % nwMinimal, "--data=%s" % tmpDir, nwMinimal]
)
assert nwGUI.mainConf.confPath == nwMinimal
qtbot.addWidget(nwGUI)
nwGUI.show()
qtbot.wait(stepDelay)
assert novelwriter.CONFIG.guiTheme == "default_dark" # The defaults should be set
assert novelwriter.CONFIG.guiSyntax == "tomorrow_night_eighties" defaultFont = mainConf.guiFont
assert novelwriter.CONFIG.guiFont != "" defaultSize = mainConf.guiFontSize
assert novelwriter.CONFIG.guiFontSize > 0
# Check GUI Colours # CHange them to nonsense values
thePalette = nwGUI.palette() mainConf.guiFont = "notafont"
assert thePalette.window().color() == QColor(54, 54, 54) mainConf.guiFontSize = 99
assert thePalette.windowText().color() == QColor(174, 174, 174)
assert thePalette.base().color() == QColor(62, 62, 62)
assert thePalette.alternateBase().color() == QColor(78, 78, 78)
assert thePalette.text().color() == QColor(174, 174, 174)
assert thePalette.toolTipBase().color() == QColor(255, 255, 192)
assert thePalette.toolTipText().color() == QColor(21, 21, 13)
assert thePalette.button().color() == QColor(62, 62, 62)
assert thePalette.buttonText().color() == QColor(174, 174, 174)
assert thePalette.brightText().color() == QColor(174, 174, 174)
assert thePalette.highlight().color() == QColor(44, 152, 247)
assert thePalette.highlightedText().color() == QColor(255, 255, 255)
assert thePalette.link().color() == QColor(44, 152, 247)
assert thePalette.linkVisited().color() == QColor(44, 152, 247)
assert nwGUI.mainTheme.statNone == [150, 152, 150] # Let the theme class set them back to default
assert nwGUI.mainTheme.statSaved == [39, 135, 78] mainTheme._setGuiFont()
assert nwGUI.mainTheme.statUnsaved == [138, 32, 32] assert mainConf.guiFont == defaultFont
assert mainConf.guiFontSize == defaultSize
# Check Syntax Colours # A second call should just restore the defaults again
assert nwGUI.mainTheme.colBack == [45, 45, 45] mainTheme._setGuiFont()
assert nwGUI.mainTheme.colText == [204, 204, 204] assert mainConf.guiFont == defaultFont
assert nwGUI.mainTheme.colLink == [102, 153, 204] assert mainConf.guiFontSize == defaultSize
assert nwGUI.mainTheme.colHead == [102, 153, 204]
assert nwGUI.mainTheme.colHeadH == [102, 153, 204]
assert nwGUI.mainTheme.colEmph == [249, 145, 57]
assert nwGUI.mainTheme.colDialN == [242, 119, 122]
assert nwGUI.mainTheme.colDialD == [153, 204, 153]
assert nwGUI.mainTheme.colDialS == [255, 204, 102]
assert nwGUI.mainTheme.colHidden == [153, 153, 153]
assert nwGUI.mainTheme.colKey == [242, 119, 122]
assert nwGUI.mainTheme.colVal == [204, 153, 204]
assert nwGUI.mainTheme.colSpell == [242, 119, 122]
assert nwGUI.mainTheme.colError == [153, 204, 153]
assert nwGUI.mainTheme.colRepTag == [102, 204, 204]
assert nwGUI.mainTheme.colMod == [249, 145, 57]
# Test Icon class # Scan for Themes
iconCache = nwGUI.mainTheme.iconCache # ===============
assert iconCache.updateTheme("invalid") is False
# Ask for a non-existent key assert mainTheme._listConf({}, "not_a_path") is False
anImg = iconCache.loadDecoration("nonsense", 20, 20)
assert isinstance(anImg, QPixmap)
assert anImg.isNull()
# Add a non-existent file and request it themeOne = os.path.join(fncDir, "themes", "themeone.conf")
iconCache.IMAGE_MAP["nonsense"] = "nofile.jpg" themeTwo = os.path.join(fncDir, "themes", "themetwo.conf")
anImg = iconCache.loadDecoration("nonsense", 20, 20) writeFile(themeOne, "# Stuff")
assert isinstance(anImg, QPixmap) writeFile(themeTwo, "# Stuff")
assert anImg.isNull()
# Get a real image, with different size parameters result = {}
anImg = iconCache.loadDecoration("wiz-back", 20, None) assert mainTheme._listConf(result, os.path.join(fncDir, "themes")) is True
assert isinstance(anImg, QPixmap) assert result["themeone"] == themeOne
assert not anImg.isNull() assert result["themetwo"] == themeTwo
assert anImg.width() == 20
assert anImg.height() >= 56
anImg = iconCache.loadDecoration("wiz-back", None, 70) # Parse Colours
assert isinstance(anImg, QPixmap) # =============
assert not anImg.isNull()
assert anImg.height() == 70
assert anImg.width() >= 24
anImg = iconCache.loadDecoration("wiz-back", 30, 70) parser = ConfigParser()
assert isinstance(anImg, QPixmap) parser["Palette"] = {
assert not anImg.isNull() "colour1": "100, 150, 200",
assert anImg.height() == 70 "colour2": "100, 150, 200, 250",
assert anImg.width() == 30 "colour3": "250, 250",
"colour4": "-10, 127, 300",
}
anImg = iconCache.loadDecoration("wiz-back", None, None) # Test the parser for several valid and invalid values
assert isinstance(anImg, QPixmap) assert mainTheme._parseColour(parser, "Palette", "colour1") == [100, 150, 200]
assert not anImg.isNull() assert mainTheme._parseColour(parser, "Palette", "colour2") == [100, 150, 200]
assert anImg.height() >= 1500 assert mainTheme._parseColour(parser, "Palette", "colour3") == [0, 0, 0]
assert anImg.width() >= 500 assert mainTheme._parseColour(parser, "Palette", "colour4") == [0, 127, 255]
assert mainTheme._parseColour(parser, "Palette", "colour5") == [0, 0, 0]
# Load icons # The palette should load with the parsed values
anIcon = iconCache.getIcon("nonsense") mainTheme._setPalette(parser, "Palette", "colour1", QPalette.Window)
assert isinstance(anIcon, QIcon) assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (100, 150, 200, 255)
assert anIcon.isNull() mainTheme._setPalette(parser, "Palette", "colour2", QPalette.Window)
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (100, 150, 200, 255)
mainTheme._setPalette(parser, "Palette", "colour3", QPalette.Window)
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 0, 0, 255)
mainTheme._setPalette(parser, "Palette", "colour4", QPalette.Window)
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 127, 255, 255)
mainTheme._setPalette(parser, "Palette", "colour5", QPalette.Window)
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (0, 0, 0, 255)
anIcon = iconCache.getIcon("novelwriter") # qtbot.stop()
assert isinstance(anIcon, QIcon)
assert not anIcon.isNull()
# Check return empty icon if file not found
iconCache.ICON_KEYS.add("testicon3")
anIcon = iconCache.getIcon("testicon3")
assert isinstance(anIcon, QIcon)
assert anIcon.isNull()
# qtbot.stopForInteraction()
nwGUI.closeMain()
nwGUI.close()
# END Test testGuiTheme_Main # END Test testGuiTheme_Main
@pytest.mark.gui
def testGuiTheme_Themes(qtbot, monkeypatch, nwGUI, fncDir):
"""Test the theme class init.
"""
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
mainTheme: GuiTheme = nwGUI.mainTheme
mainConf: Config = nwGUI.mainConf
# List Themes
# ===========
shutil.copy(
os.path.join(mainConf.assetPath, "themes", "default_dark.conf"),
os.path.join(fncDir, "themes")
)
shutil.copy(
os.path.join(mainConf.assetPath, "themes", "default.conf"),
os.path.join(fncDir, "themes")
)
writeFile(os.path.join(fncDir, "themes", "default.qss"), "/* Stuff */")
# Load the theme info
themesList = mainTheme.listThemes()
assert themesList[0] == ("default_dark", "Default Dark Theme")
assert themesList[1] == ("default", "Default Theme")
# A second call should returned the cached list
assert mainTheme.listThemes() == mainTheme._themeList
# Check handling of broken theme settings
mainConf.guiTheme = "not_a_theme"
assert mainTheme.loadTheme() is False
# Check handling of unreadable file
mainConf.guiTheme = "default"
with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError)
assert mainTheme.loadTheme() is False
# Load Default Theme
# ==================
# Set a mock colour for the window background
mainTheme._guiPalette.color(QPalette.Window).setRgb(0, 0, 0, 0)
# Load the default theme
mainConf.guiTheme = "default"
assert mainTheme.loadTheme() is True
# This should load a standard palette
wCol = QApplication.style().standardPalette().color(QPalette.Window).getRgb()
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == wCol
# Load Default Dark Theme
# =======================
mainConf.guiTheme = "default_dark"
assert mainTheme.loadTheme() is True
# Check a few values
assert mainTheme._guiPalette.color(QPalette.Window).getRgb() == (54, 54, 54, 255)
assert mainTheme._guiPalette.color(QPalette.WindowText).getRgb() == (174, 174, 174, 255)
assert mainTheme._guiPalette.color(QPalette.Base).getRgb() == (62, 62, 62, 255)
assert mainTheme._guiPalette.color(QPalette.AlternateBase).getRgb() == (78, 78, 78, 255)
# qtbot.stop()
# END Test testGuiTheme_Themes