Add tests for the theme and icons files
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
[
|
||||
"alert_error",
|
||||
"alert_info",
|
||||
"alert_question",
|
||||
"alert_warn",
|
||||
|
||||
"cls_archive",
|
||||
"cls_character",
|
||||
"cls_custom",
|
||||
"cls_entity",
|
||||
"cls_none",
|
||||
"cls_novel",
|
||||
"cls_object",
|
||||
"cls_plot",
|
||||
"cls_template",
|
||||
"cls_timeline",
|
||||
"cls_trash",
|
||||
"cls_world",
|
||||
|
||||
"prj_folder",
|
||||
"prj_document",
|
||||
"prj_title",
|
||||
"prj_chapter",
|
||||
"prj_scene",
|
||||
"prj_note",
|
||||
|
||||
"fmt_bold",
|
||||
"fmt_italic",
|
||||
"fmt_mark",
|
||||
"fmt_strike",
|
||||
"fmt_subscript",
|
||||
"fmt_superscript",
|
||||
"fmt_underline",
|
||||
"fmt_toolbar",
|
||||
|
||||
"search",
|
||||
"search_cancel",
|
||||
"search_case",
|
||||
"search_loop",
|
||||
"search_preserve",
|
||||
"search_project",
|
||||
"search_regex",
|
||||
"search_replace",
|
||||
"search_word",
|
||||
|
||||
"bullet-off",
|
||||
"bullet-on",
|
||||
"unfold-hide",
|
||||
"unfold-show",
|
||||
|
||||
"sb_build",
|
||||
"sb_details",
|
||||
"sb_novel",
|
||||
"sb_outline",
|
||||
"sb_project",
|
||||
"sb_search",
|
||||
"sb_stats",
|
||||
|
||||
"theme_light",
|
||||
"theme_dark",
|
||||
"theme_auto",
|
||||
|
||||
"add",
|
||||
"bookmarks",
|
||||
"browse",
|
||||
"build_settings",
|
||||
"cancel",
|
||||
"checked",
|
||||
"chevron_down",
|
||||
"chevron_left",
|
||||
"chevron_right",
|
||||
"chevron_up",
|
||||
"close",
|
||||
"copy",
|
||||
"document_add",
|
||||
"document",
|
||||
"edit",
|
||||
"exclude",
|
||||
"export",
|
||||
"filter",
|
||||
"fit_height",
|
||||
"fit_width",
|
||||
"folder",
|
||||
"font",
|
||||
"import",
|
||||
"language",
|
||||
"lines",
|
||||
"list",
|
||||
"margin_bottom",
|
||||
"margin_left",
|
||||
"margin_right",
|
||||
"margin_top",
|
||||
"maximise",
|
||||
"minimise",
|
||||
"more_arrow",
|
||||
"more_vertical",
|
||||
"noncheckable",
|
||||
"open",
|
||||
"panel",
|
||||
"pin",
|
||||
"project_copy",
|
||||
"quote",
|
||||
"refresh",
|
||||
"remove",
|
||||
"revert",
|
||||
"settings",
|
||||
"star",
|
||||
"stats",
|
||||
"text",
|
||||
"timer_off",
|
||||
"timer",
|
||||
"unchecked",
|
||||
"view"
|
||||
]
|
||||
@@ -20,6 +20,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from configparser import ConfigParser
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, Mock
|
||||
@@ -563,3 +565,114 @@ def testGuiTheme_LoadDecorations(monkeypatch):
|
||||
assert iconCache.getHeaderDecorationNarrow(4) == iconCache._headerDecNarrow[4]
|
||||
assert iconCache.getHeaderDecorationNarrow(5) == iconCache._headerDecNarrow[5]
|
||||
assert iconCache.getHeaderDecorationNarrow(6) == iconCache._headerDecNarrow[5]
|
||||
|
||||
|
||||
THEMES = []
|
||||
_listContent(THEMES, CONFIG.assetPath("themes"), ".conf")
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@pytest.mark.parametrize("theme", [a.stem for a in THEMES])
|
||||
def testGuiTheme_CheckTheme(theme):
|
||||
"""Test loading all themes."""
|
||||
themes = GuiTheme()
|
||||
themes.iconCache = MagicMock()
|
||||
themes._scanThemes(THEMES)
|
||||
|
||||
assert theme in themes.colourThemes
|
||||
current = themes.colourThemes[theme]
|
||||
if current.dark:
|
||||
CONFIG.darkTheme = theme
|
||||
CONFIG.themeMode = nwTheme.DARK
|
||||
else:
|
||||
CONFIG.lightTheme = theme
|
||||
CONFIG.themeMode = nwTheme.LIGHT
|
||||
|
||||
# Check loading
|
||||
themes.loadTheme()
|
||||
assert themes._meta.name == current.name
|
||||
assert themes.isDarkTheme == current.dark
|
||||
|
||||
# Check completeness
|
||||
parser = ConfigParser()
|
||||
parser.read(current.path, encoding="utf-8")
|
||||
|
||||
sections = ["Main", "Base", "Project", "Palette", "GUI", "Syntax"]
|
||||
assert sorted(parser.sections()) == sorted(sections)
|
||||
|
||||
structure = {
|
||||
"Main": [
|
||||
"name", "mode", # The rest are not required
|
||||
],
|
||||
"Base": [
|
||||
"default", "faded", "red", "orange", "yellow", "green", "cyan",
|
||||
"blue", "purple",
|
||||
],
|
||||
"Project": [
|
||||
"root", "folder", "file", "title", "chapter", "scene", "note",
|
||||
],
|
||||
"Palette": [
|
||||
"window", "windowtext", "base", "alternatebase", "text",
|
||||
"tooltipbase", "tooltiptext", "button", "buttontext", "brighttext",
|
||||
"highlight", "highlightedtext", "link", "linkvisited",
|
||||
],
|
||||
"GUI": [
|
||||
"helptext", "fadedtext", "errortext",
|
||||
],
|
||||
"Syntax": [
|
||||
"background", "text", "link", "headertext", "headertag",
|
||||
"emphasis", "dialog", "altdialog", "hidden", "note", "shortcode",
|
||||
"keyword", "tag", "value", "optional", "spellcheckline",
|
||||
"errorline", "replacetag", "modifier", "texthighlight",
|
||||
],
|
||||
}
|
||||
optional = ["description", "author", "credit", "url", "license", "licenseurl"]
|
||||
missing = []
|
||||
for section, options in structure.items():
|
||||
missing.extend(opt for opt in options if opt not in parser[section])
|
||||
assert missing == [], "Missing options in theme file"
|
||||
|
||||
# Check deprecated
|
||||
deprecated = []
|
||||
for section in sections:
|
||||
deprecated.extend(
|
||||
opt for opt in parser[section]
|
||||
if opt not in structure[section] and opt not in optional
|
||||
)
|
||||
assert deprecated == [], "Deprecated options in theme file"
|
||||
|
||||
|
||||
ICONS = []
|
||||
_listContent(ICONS, CONFIG.assetPath("icons"), ".icons")
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
@pytest.mark.parametrize("icons", [a.stem for a in ICONS])
|
||||
def testGuiTheme_CheckIcons(icons, tstPaths):
|
||||
"""Test loading all icons."""
|
||||
keysFile: Path = tstPaths.filesDir / "all_icons.json"
|
||||
iconKeys = json.loads(keysFile.read_text(encoding="utf-8"))
|
||||
assert isinstance(iconKeys, list)
|
||||
|
||||
CONFIG.lightTheme = DEF_GUI_LIGHT
|
||||
CONFIG.themeMode = nwTheme.LIGHT
|
||||
|
||||
themes = GuiTheme()
|
||||
themes.initThemes()
|
||||
iconCache = themes.iconCache
|
||||
|
||||
assert icons in iconCache.iconThemes
|
||||
current = iconCache.iconThemes[icons]
|
||||
CONFIG.iconTheme = icons
|
||||
|
||||
# Check loading
|
||||
iconCache.loadTheme(icons)
|
||||
assert iconCache._meta.name == current.name
|
||||
|
||||
# Check completeness
|
||||
missing = [key for key in iconKeys if key not in iconCache._svgData]
|
||||
assert missing == [], "Missing keys in icons file"
|
||||
|
||||
# Check deprecated
|
||||
deprecated = [key for key in iconCache._svgData if key not in iconKeys]
|
||||
assert deprecated == [], "Deprecated keys in icons file"
|
||||
|
||||
@@ -33,6 +33,7 @@ from utils.common import ROOT_DIR
|
||||
UTILS = Path(__file__).parent
|
||||
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
||||
ICONS = [
|
||||
# Remember to also update tests/files/all_icons.json for test coverage
|
||||
"alert_error",
|
||||
"alert_info",
|
||||
"alert_question",
|
||||
|
||||
Reference in New Issue
Block a user