mirror of
https://github.com/imarkoff/Marble-shell-theme.git
synced 2025-09-16 08:18:41 -07:00
Cover GDM module with tests, added FilesLabelerFactory, renamed GdmBuilder
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# This file installs Marble shell theme for GNOME DE
|
# This file installs Marble shell theme for GNOME DE
|
||||||
# Copyright (C) 2023-2025 Vladyslav Hroshev
|
# Copyright (C) 2023-2025 Vladyslav Hroshev
|
||||||
|
import os
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
@@ -22,6 +22,7 @@ from scripts.install.colors_definer import ColorsDefiner
|
|||||||
from scripts.install.global_theme_installer import GlobalThemeInstaller
|
from scripts.install.global_theme_installer import GlobalThemeInstaller
|
||||||
from scripts.install.local_theme_installer import LocalThemeInstaller
|
from scripts.install.local_theme_installer import LocalThemeInstaller
|
||||||
from scripts.utils.gnome import apply_gnome_theme
|
from scripts.utils.gnome import apply_gnome_theme
|
||||||
|
from scripts.utils.logger.console import Console
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -31,6 +32,12 @@ def main():
|
|||||||
installer_class = GlobalThemeInstaller if args.gdm else LocalThemeInstaller
|
installer_class = GlobalThemeInstaller if args.gdm else LocalThemeInstaller
|
||||||
installer = installer_class(args, colors_definer)
|
installer = installer_class(args, colors_definer)
|
||||||
|
|
||||||
|
if args.gdm:
|
||||||
|
if os.getuid() != 0:
|
||||||
|
Console().Line().error(
|
||||||
|
"Global installation requires root privileges. Please run the script as root.")
|
||||||
|
return
|
||||||
|
|
||||||
if args.remove or args.reinstall:
|
if args.remove or args.reinstall:
|
||||||
installer.remove()
|
installer.remove()
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
from scripts.install.theme_installer import ThemeInstaller
|
from scripts.install.theme_installer import ThemeInstaller
|
||||||
from scripts.utils.global_theme.gdm import GDMTheme
|
from scripts.utils.global_theme.gdm import GDMTheme
|
||||||
from scripts.utils.global_theme.gdm_builder import GdmBuilder
|
from scripts.utils.global_theme.gdm_builder import GDMThemeBuilder
|
||||||
from scripts.utils.logger.console import Console, Color, Format
|
from scripts.utils.logger.console import Console, Color, Format
|
||||||
|
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ class GlobalThemeInstaller(ThemeInstaller):
|
|||||||
print("GDM theme removed successfully.")
|
print("GDM theme removed successfully.")
|
||||||
|
|
||||||
def _define_theme(self):
|
def _define_theme(self):
|
||||||
gdm_builder = GdmBuilder(self.colors)
|
gdm_builder = GDMThemeBuilder(self.colors)
|
||||||
gdm_builder.with_mode(self.args.mode)
|
gdm_builder.with_mode(self.args.mode)
|
||||||
gdm_builder.with_filled(self.args.filled)
|
gdm_builder.with_filled(self.args.filled)
|
||||||
self.theme = gdm_builder.build()
|
self.theme = gdm_builder.build()
|
||||||
|
@@ -1,15 +1,28 @@
|
|||||||
import os
|
import os
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
from typing import Tuple, TypeAlias
|
from typing import Tuple, TypeAlias
|
||||||
|
|
||||||
LabeledFileGroup: TypeAlias = Tuple[str, str]
|
LabeledFileGroup: TypeAlias = Tuple[str, str]
|
||||||
|
|
||||||
|
|
||||||
|
class FilesLabelerFactory(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def create(self, temp_folder: str, *files_to_update_references: str) -> 'FilesLabeler':
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FilesLabelerFactoryImpl(FilesLabelerFactory):
|
||||||
|
def create(self, temp_folder: str, *files_to_update_references: str) -> 'FilesLabeler':
|
||||||
|
return FilesLabeler(temp_folder, *files_to_update_references)
|
||||||
|
|
||||||
|
|
||||||
class FilesLabeler:
|
class FilesLabeler:
|
||||||
def __init__(self, directory: str, *args: str):
|
def __init__(self, directory: str, *files_to_update_references: str):
|
||||||
"""
|
"""
|
||||||
Initialize the working directory and files to change
|
Initialize the working directory and files to change
|
||||||
"""
|
"""
|
||||||
self.directory = directory
|
self.directory = directory
|
||||||
self.files = args
|
self.files = files_to_update_references
|
||||||
|
|
||||||
def append_label(self, label: str):
|
def append_label(self, label: str):
|
||||||
"""
|
"""
|
||||||
|
@@ -6,6 +6,7 @@ from scripts.install.colors_definer import ColorsDefiner
|
|||||||
from scripts.types.installation_color import InstallationMode
|
from scripts.types.installation_color import InstallationMode
|
||||||
from scripts.utils.alternatives_updater import AlternativesUpdater, PathString
|
from scripts.utils.alternatives_updater import AlternativesUpdater, PathString
|
||||||
from scripts.utils.command_runner.subprocess_command_runner import SubprocessCommandRunner
|
from scripts.utils.command_runner.subprocess_command_runner import SubprocessCommandRunner
|
||||||
|
from scripts.utils.files_labeler import FilesLabelerFactoryImpl
|
||||||
from scripts.utils.global_theme.gdm import GDMTheme
|
from scripts.utils.global_theme.gdm import GDMTheme
|
||||||
from scripts.utils.global_theme.gdm_installer import GDMThemeInstaller
|
from scripts.utils.global_theme.gdm_installer import GDMThemeInstaller
|
||||||
from scripts.utils.global_theme.gdm_preparer import GDMThemePreparer
|
from scripts.utils.global_theme.gdm_preparer import GDMThemePreparer
|
||||||
@@ -17,7 +18,7 @@ from scripts.utils.logger.logger import LoggerFactory
|
|||||||
from scripts.utils.theme.gnome_shell_theme_builder import GnomeShellThemeBuilder
|
from scripts.utils.theme.gnome_shell_theme_builder import GnomeShellThemeBuilder
|
||||||
|
|
||||||
|
|
||||||
class GdmBuilder:
|
class GDMThemeBuilder:
|
||||||
"""
|
"""
|
||||||
Builder class for creating GDMTheme instances with configurable components.
|
Builder class for creating GDMTheme instances with configurable components.
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ class GdmBuilder:
|
|||||||
automatically resolved during build() if not provided.
|
automatically resolved during build() if not provided.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
builder = GdmBuilder(colors_provider)
|
builder = GMDThemeBuilder(colors_provider)
|
||||||
theme = builder.with_mode("dark").with_filled(True).build()
|
theme = builder.with_mode("dark").with_filled(True).build()
|
||||||
"""
|
"""
|
||||||
def __init__(self, colors_provider: ColorsDefiner):
|
def __init__(self, colors_provider: ColorsDefiner):
|
||||||
@@ -46,42 +47,42 @@ class GdmBuilder:
|
|||||||
self._installer: Optional[GDMThemeInstaller] = None
|
self._installer: Optional[GDMThemeInstaller] = None
|
||||||
self._remover: Optional[GDMThemeRemover] = None
|
self._remover: Optional[GDMThemeRemover] = None
|
||||||
|
|
||||||
def with_mode(self, mode: InstallationMode | None) -> 'GdmBuilder':
|
def with_mode(self, mode: InstallationMode | None) -> 'GDMThemeBuilder':
|
||||||
"""Set the mode for the theme."""
|
"""Set the mode for the theme."""
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_filled(self, is_filled=True) -> 'GdmBuilder':
|
def with_filled(self, is_filled=True) -> 'GDMThemeBuilder':
|
||||||
"""Set the filled state for the theme."""
|
"""Set the filled state for the theme."""
|
||||||
self._is_filled = is_filled
|
self._is_filled = is_filled
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_logger_factory(self, logger_factory: LoggerFactory) -> 'GdmBuilder':
|
def with_logger_factory(self, logger_factory: LoggerFactory) -> 'GDMThemeBuilder':
|
||||||
"""Inject a logger factory for logging purposes."""
|
"""Inject a logger factory for logging purposes."""
|
||||||
self._logger_factory = logger_factory
|
self._logger_factory = logger_factory
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_gresource(self, gresource: Gresource) -> 'GdmBuilder':
|
def with_gresource(self, gresource: Gresource) -> 'GDMThemeBuilder':
|
||||||
"""Inject a gresource instance for managing gresource files."""
|
"""Inject a gresource instance for managing gresource files."""
|
||||||
self._gresource = gresource
|
self._gresource = gresource
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_ubuntu_gdm_alternatives_updater(self, alternatives_updater: UbuntuGDMAlternativesUpdater) -> 'GdmBuilder':
|
def with_ubuntu_gdm_alternatives_updater(self, alternatives_updater: UbuntuGDMAlternativesUpdater) -> 'GDMThemeBuilder':
|
||||||
"""Inject an alternatives updater for managing GDM alternatives."""
|
"""Inject an alternatives updater for managing GDM alternatives."""
|
||||||
self._ubuntu_gdm_alternatives_updater = alternatives_updater
|
self._ubuntu_gdm_alternatives_updater = alternatives_updater
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_preparer(self, preparer: GDMThemePreparer) -> 'GdmBuilder':
|
def with_preparer(self, preparer: GDMThemePreparer) -> 'GDMThemeBuilder':
|
||||||
"""Inject a preparer for preparing the theme."""
|
"""Inject a preparer for preparing the theme."""
|
||||||
self._preparer = preparer
|
self._preparer = preparer
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_installer(self, installer: GDMThemeInstaller) -> 'GdmBuilder':
|
def with_installer(self, installer: GDMThemeInstaller) -> 'GDMThemeBuilder':
|
||||||
"""Inject an installer for installing the theme."""
|
"""Inject an installer for installing the theme."""
|
||||||
self._installer = installer
|
self._installer = installer
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def with_remover(self, remover: GDMThemeRemover) -> 'GdmBuilder':
|
def with_remover(self, remover: GDMThemeRemover) -> 'GDMThemeBuilder':
|
||||||
"""Inject a remover for removing the theme."""
|
"""Inject a remover for removing the theme."""
|
||||||
self._remover = remover
|
self._remover = remover
|
||||||
return self
|
return self
|
||||||
@@ -141,13 +142,15 @@ class GdmBuilder:
|
|||||||
"""Create a GDMThemePreparer if not explicitly provided."""
|
"""Create a GDMThemePreparer if not explicitly provided."""
|
||||||
if self._preparer: return
|
if self._preparer: return
|
||||||
theme_builder = GnomeShellThemeBuilder(self.colors_provider)
|
theme_builder = GnomeShellThemeBuilder(self.colors_provider)
|
||||||
|
files_labeler_factory = FilesLabelerFactoryImpl()
|
||||||
self._preparer = GDMThemePreparer(
|
self._preparer = GDMThemePreparer(
|
||||||
temp_folder=self._temp_folder,
|
temp_folder=self._temp_folder,
|
||||||
default_mode=self._mode,
|
default_mode=self._mode,
|
||||||
is_filled=self._is_filled,
|
is_filled=self._is_filled,
|
||||||
gresource=self._gresource,
|
gresource=self._gresource,
|
||||||
theme_builder=theme_builder,
|
theme_builder=theme_builder,
|
||||||
logger_factory=self._logger_factory
|
logger_factory=self._logger_factory,
|
||||||
|
files_labeler_factory=files_labeler_factory,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _resolve_installer(self):
|
def _resolve_installer(self):
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
from scripts.utils.files_labeler import FilesLabelerFactory
|
||||||
from scripts.utils.global_theme.gdm_theme_prepare import GDMThemePrepare
|
from scripts.utils.global_theme.gdm_theme_prepare import GDMThemePrepare
|
||||||
from scripts.utils.gresource.gresource import Gresource
|
from scripts.utils.gresource.gresource import Gresource
|
||||||
from scripts.utils.logger.logger import LoggerFactory
|
from scripts.utils.logger.logger import LoggerFactory
|
||||||
@@ -19,13 +20,16 @@ class GDMThemePreparer:
|
|||||||
def __init__(self, temp_folder: str, default_mode: str | None, is_filled: bool,
|
def __init__(self, temp_folder: str, default_mode: str | None, is_filled: bool,
|
||||||
gresource: Gresource,
|
gresource: Gresource,
|
||||||
theme_builder: GnomeShellThemeBuilder,
|
theme_builder: GnomeShellThemeBuilder,
|
||||||
logger_factory: LoggerFactory):
|
logger_factory: LoggerFactory,
|
||||||
|
files_labeler_factory: FilesLabelerFactory):
|
||||||
"""
|
"""
|
||||||
:param temp_folder: Temporary folder for extracted theme files
|
:param temp_folder: Temporary folder for extracted theme files
|
||||||
:param default_mode: Default theme mode to use if not specified in CSS filename
|
:param default_mode: Default theme mode to use if not specified in CSS filename
|
||||||
:param is_filled: Whether to generate filled (True) or outlined (False) styles
|
:param is_filled: Whether to generate filled (True) or dimmed (False) styles
|
||||||
:param gresource: Gresource instance for managing gresource files
|
:param gresource: Gresource instance for managing gresource files
|
||||||
:param theme_builder: Theme builder instance for creating themes
|
:param theme_builder: Theme builder instance for creating themes
|
||||||
|
:param logger_factory: Logger factory for logging messages
|
||||||
|
:param files_labeler_factory: Factory for creating FilesLabeler instances
|
||||||
"""
|
"""
|
||||||
self.temp_folder = temp_folder
|
self.temp_folder = temp_folder
|
||||||
self.gresource_temp_folder = gresource.temp_folder
|
self.gresource_temp_folder = gresource.temp_folder
|
||||||
@@ -36,6 +40,7 @@ class GDMThemePreparer:
|
|||||||
self.gresource = gresource
|
self.gresource = gresource
|
||||||
self.theme_builder = theme_builder
|
self.theme_builder = theme_builder
|
||||||
self.logger_factory = logger_factory
|
self.logger_factory = logger_factory
|
||||||
|
self.files_labeler_factory = files_labeler_factory
|
||||||
|
|
||||||
def use_backup_as_source(self):
|
def use_backup_as_source(self):
|
||||||
"""Use backup gresource file for extraction"""
|
"""Use backup gresource file for extraction"""
|
||||||
@@ -72,11 +77,12 @@ class GDMThemePreparer:
|
|||||||
theme.prepare()
|
theme.prepare()
|
||||||
|
|
||||||
theme_file = os.path.join(self.gresource_temp_folder, file_name)
|
theme_file = os.path.join(self.gresource_temp_folder, file_name)
|
||||||
return GDMThemePrepare(theme=theme, theme_file=theme_file, label=mode)
|
files_labeler = self.files_labeler_factory.create(
|
||||||
|
theme.temp_folder, theme.main_styles)
|
||||||
|
return GDMThemePrepare(
|
||||||
|
theme=theme, theme_file=theme_file, label=mode, files_labeler=files_labeler)
|
||||||
|
|
||||||
def _setup_theme_builder(self, file_name: str, mode: str):
|
def _setup_theme_builder(self, file_name: str, mode: str):
|
||||||
self.theme_builder.with_temp_folder(self.temp_folder)
|
|
||||||
|
|
||||||
theme_name = file_name.replace(".css", "")
|
theme_name = file_name.replace(".css", "")
|
||||||
|
|
||||||
(self.theme_builder
|
(self.theme_builder
|
||||||
|
@@ -12,15 +12,18 @@ class GDMThemePrepare:
|
|||||||
- CSS property and keyword removal for customization
|
- CSS property and keyword removal for customization
|
||||||
- Theme installation with color adjustments
|
- Theme installation with color adjustments
|
||||||
"""
|
"""
|
||||||
def __init__(self, theme: Theme, theme_file: str, label: str = None):
|
def __init__(self, theme: Theme, theme_file: str, label: str | None,
|
||||||
|
files_labeler: FilesLabeler):
|
||||||
"""
|
"""
|
||||||
:param theme: The theme object to prepare
|
:param theme: The theme object to prepare
|
||||||
:param theme_file: Path to the original decompiled CSS file
|
:param theme_file: Path to the original decompiled CSS file
|
||||||
:param label: Optional label for the theme (e.g. "dark", "light")
|
:param label: Optional label for the theme (e.g. "dark", "light")
|
||||||
|
:param files_labeler: FilesLabeler instance for labeling files
|
||||||
"""
|
"""
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.theme_file = theme_file
|
self.theme_file = theme_file
|
||||||
self.label = label
|
self.label = label
|
||||||
|
self.files_labeler = files_labeler
|
||||||
|
|
||||||
def label_theme(self):
|
def label_theme(self):
|
||||||
"""
|
"""
|
||||||
@@ -31,8 +34,7 @@ class GDMThemePrepare:
|
|||||||
if self.label is None:
|
if self.label is None:
|
||||||
raise ValueError("Label is not set for the theme.")
|
raise ValueError("Label is not set for the theme.")
|
||||||
|
|
||||||
files_labeler = FilesLabeler(self.theme.temp_folder, self.theme.main_styles)
|
self.files_labeler.append_label(self.label)
|
||||||
files_labeler.append_label(self.label)
|
|
||||||
|
|
||||||
def remove_keywords(self, *args: str):
|
def remove_keywords(self, *args: str):
|
||||||
"""Remove specific keywords from the theme file"""
|
"""Remove specific keywords from the theme file"""
|
||||||
@@ -52,7 +54,7 @@ class GDMThemePrepare:
|
|||||||
:param trigger: String marker used to identify installed themes
|
:param trigger: String marker used to identify installed themes
|
||||||
"""
|
"""
|
||||||
with open(self.theme_file, 'r') as gnome_theme:
|
with open(self.theme_file, 'r') as gnome_theme:
|
||||||
gnome_styles = gnome_theme.read() + trigger
|
gnome_styles = gnome_theme.read() + '\n' + trigger + '\n'
|
||||||
self.theme.add_to_start(gnome_styles)
|
self.theme.add_to_start(gnome_styles)
|
||||||
|
|
||||||
def install(self, hue: int, color: str, sat: int | None, destination: str):
|
def install(self, hue: int, color: str, sat: int | None, destination: str):
|
||||||
|
@@ -17,7 +17,7 @@ class UbuntuGDMAlternativesUpdater:
|
|||||||
"""
|
"""
|
||||||
:param alternatives_updater: Handler for update-alternatives operations
|
:param alternatives_updater: Handler for update-alternatives operations
|
||||||
"""
|
"""
|
||||||
self.ubuntu_gresource_link = config.ubuntu_gresource_link
|
self.ubuntu_gresource_link_name = config.ubuntu_gresource_link
|
||||||
self.destination_dir = config.global_gnome_shell_theme
|
self.destination_dir = config.global_gnome_shell_theme
|
||||||
self.destination_file = config.gnome_shell_gresource
|
self.destination_file = config.gnome_shell_gresource
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ class UbuntuGDMAlternativesUpdater:
|
|||||||
self._update_gresource_paths()
|
self._update_gresource_paths()
|
||||||
|
|
||||||
def _update_gresource_paths(self):
|
def _update_gresource_paths(self):
|
||||||
self.ubuntu_gresource_path = os.path.join(self.destination_dir, self.ubuntu_gresource_link)
|
self.ubuntu_gresource_path = os.path.join(self.destination_dir, self.ubuntu_gresource_link_name)
|
||||||
self.gnome_gresource_path = os.path.join(self.destination_dir, self.destination_file)
|
self.gnome_gresource_path = os.path.join(self.destination_dir, self.destination_file)
|
||||||
|
|
||||||
def with_custom_destination(self, destination_dir: str, destination_file: str):
|
def with_custom_destination(self, destination_dir: str, destination_file: str):
|
||||||
@@ -47,7 +47,7 @@ class UbuntuGDMAlternativesUpdater:
|
|||||||
"""
|
"""
|
||||||
self.alternatives_updater.install_and_set(
|
self.alternatives_updater.install_and_set(
|
||||||
link=self.ubuntu_gresource_path,
|
link=self.ubuntu_gresource_path,
|
||||||
name=self.ubuntu_gresource_link,
|
name=self.ubuntu_gresource_link_name,
|
||||||
path=self.gnome_gresource_path,
|
path=self.gnome_gresource_path,
|
||||||
priority=priority
|
priority=priority
|
||||||
)
|
)
|
||||||
@@ -60,6 +60,6 @@ class UbuntuGDMAlternativesUpdater:
|
|||||||
the system to fall back to the default GDM theme.
|
the system to fall back to the default GDM theme.
|
||||||
"""
|
"""
|
||||||
self.alternatives_updater.remove(
|
self.alternatives_updater.remove(
|
||||||
name=self.ubuntu_gresource_link,
|
name=self.ubuntu_gresource_link_name,
|
||||||
path=self.gnome_gresource_path
|
path=self.gnome_gresource_path
|
||||||
)
|
)
|
||||||
|
@@ -10,10 +10,10 @@ def remove_properties(file, *args):
|
|||||||
with open(file, "r") as read_file:
|
with open(file, "r") as read_file:
|
||||||
content = read_file.read()
|
content = read_file.read()
|
||||||
|
|
||||||
for line in content.splitlines():
|
for i, line in enumerate(content.splitlines()):
|
||||||
if not any(prop in line for prop in args):
|
if not any(prop in line for prop in args):
|
||||||
new_content += line + "\n"
|
new_content += line + "\n"
|
||||||
elif "}" in line:
|
elif "}" in line and not "{" in line:
|
||||||
new_content += "}\n"
|
new_content += "}\n"
|
||||||
|
|
||||||
with open(file, "w") as write_file:
|
with open(file, "w") as write_file:
|
||||||
|
0
tests/utils/global_theme/__init__.py
Normal file
0
tests/utils/global_theme/__init__.py
Normal file
81
tests/utils/global_theme/test_gdm.py
Normal file
81
tests/utils/global_theme/test_gdm.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
from scripts.utils.global_theme.gdm import GDMTheme
|
||||||
|
from scripts.utils.global_theme.gdm_installer import GDMThemeInstaller
|
||||||
|
from scripts.utils.global_theme.gdm_preparer import GDMThemePreparer
|
||||||
|
from scripts.utils.global_theme.gdm_remover import GDMThemeRemover
|
||||||
|
|
||||||
|
|
||||||
|
class GDMTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.preparer = Mock(spec=GDMThemePreparer)
|
||||||
|
self.installer = Mock(spec=GDMThemeInstaller)
|
||||||
|
self.remover = Mock(spec=GDMThemeRemover)
|
||||||
|
|
||||||
|
self.gdm = GDMTheme(self.preparer, self.installer, self.remover)
|
||||||
|
|
||||||
|
def test_prepare_uses_backup_if_installed(self):
|
||||||
|
self.installer.is_installed.return_value = True
|
||||||
|
|
||||||
|
self.gdm.prepare()
|
||||||
|
|
||||||
|
self.preparer.use_backup_as_source.assert_called_once()
|
||||||
|
|
||||||
|
def test_prepare_does_not_use_backup_if_not_installed(self):
|
||||||
|
self.installer.is_installed.return_value = False
|
||||||
|
|
||||||
|
self.gdm.prepare()
|
||||||
|
|
||||||
|
self.preparer.use_backup_as_source.assert_not_called()
|
||||||
|
|
||||||
|
def test_prepare_calls_preparer_prepare_and_sets_themes(self):
|
||||||
|
mock_theme = Mock()
|
||||||
|
self.preparer.prepare.return_value = [mock_theme]
|
||||||
|
|
||||||
|
self.gdm.prepare()
|
||||||
|
|
||||||
|
self.preparer.prepare.assert_called_once()
|
||||||
|
self.assertEqual(self.gdm.themes, [mock_theme])
|
||||||
|
|
||||||
|
def test_install_correctly_passes_arguments_to_installer_compile(self):
|
||||||
|
hue = 100
|
||||||
|
name = "test_theme"
|
||||||
|
sat = 0.5
|
||||||
|
|
||||||
|
self.gdm.install(hue, name, sat)
|
||||||
|
|
||||||
|
self.installer.compile.assert_called_once_with(self.gdm.themes, hue, name, sat)
|
||||||
|
|
||||||
|
def test_install_calls_installer_backup_if_not_installed(self):
|
||||||
|
self.installer.is_installed.return_value = False
|
||||||
|
|
||||||
|
self.gdm.install(100, "test_theme")
|
||||||
|
|
||||||
|
self.installer.backup.assert_called_once()
|
||||||
|
|
||||||
|
def test_install_does_not_call_installer_backup_if_installed(self):
|
||||||
|
self.installer.is_installed.return_value = True
|
||||||
|
|
||||||
|
self.gdm.install(100, "test_theme")
|
||||||
|
|
||||||
|
self.installer.backup.assert_not_called()
|
||||||
|
|
||||||
|
def test_install_calls_installer_install(self):
|
||||||
|
self.gdm.install(100, "test_theme")
|
||||||
|
|
||||||
|
self.installer.install.assert_called_once()
|
||||||
|
|
||||||
|
def test_remove_calls_installer_remove_if_installed(self):
|
||||||
|
self.installer.is_installed.return_value = True
|
||||||
|
|
||||||
|
self.gdm.remove()
|
||||||
|
|
||||||
|
self.remover.remove.assert_called_once()
|
||||||
|
|
||||||
|
def test_remove_calls_installer_warn_if_not_installed(self):
|
||||||
|
self.installer.is_installed.return_value = False
|
||||||
|
|
||||||
|
self.gdm.remove()
|
||||||
|
|
||||||
|
self.remover.remove.assert_not_called()
|
155
tests/utils/global_theme/test_gdm_builder.py
Normal file
155
tests/utils/global_theme/test_gdm_builder.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
from scripts.types.installation_color import InstallationMode
|
||||||
|
from scripts.utils.global_theme.gdm_builder import GDMThemeBuilder
|
||||||
|
|
||||||
|
|
||||||
|
class GDMBuilderTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.colors_provider = Mock()
|
||||||
|
self.builder = GDMThemeBuilder(colors_provider=self.colors_provider)
|
||||||
|
|
||||||
|
def test_with_mode_sets_correct_mode(self):
|
||||||
|
self.builder._mode = None
|
||||||
|
mode: InstallationMode = "dark"
|
||||||
|
|
||||||
|
builder = self.builder.with_mode(mode)
|
||||||
|
|
||||||
|
self.assertEqual(builder._mode, mode)
|
||||||
|
|
||||||
|
def test_with_filled_sets_correct_filled_state(self):
|
||||||
|
self.builder._is_filled = False
|
||||||
|
is_filled = True
|
||||||
|
|
||||||
|
builder = self.builder.with_filled(is_filled)
|
||||||
|
|
||||||
|
self.assertEqual(builder._is_filled, is_filled)
|
||||||
|
|
||||||
|
def test_with_logger_factory_sets_specified_logger_factory(self):
|
||||||
|
logger_factory = Mock()
|
||||||
|
builder = self.builder.with_logger_factory(logger_factory)
|
||||||
|
self.assertEqual(builder._logger_factory, logger_factory)
|
||||||
|
|
||||||
|
def test_with_gresource_sets_specified_gresource(self):
|
||||||
|
gresource = Mock()
|
||||||
|
builder = self.builder.with_gresource(gresource)
|
||||||
|
self.assertEqual(builder._gresource, gresource)
|
||||||
|
|
||||||
|
def test_with_ubuntu_gdm_alternatives_updater_sets_specified_updater(self):
|
||||||
|
alternatives_updater = Mock()
|
||||||
|
builder = self.builder.with_ubuntu_gdm_alternatives_updater(alternatives_updater)
|
||||||
|
self.assertEqual(builder._ubuntu_gdm_alternatives_updater, alternatives_updater)
|
||||||
|
|
||||||
|
def test_with_preparer_sets_specified_preparer(self):
|
||||||
|
preparer = Mock()
|
||||||
|
builder = self.builder.with_preparer(preparer)
|
||||||
|
self.assertEqual(builder._preparer, preparer)
|
||||||
|
|
||||||
|
def test_with_installer_sets_specified_installer(self):
|
||||||
|
installer = Mock()
|
||||||
|
builder = self.builder.with_installer(installer)
|
||||||
|
self.assertEqual(builder._installer, installer)
|
||||||
|
|
||||||
|
def test_with_remover_sets_specified_remover(self):
|
||||||
|
remover = Mock()
|
||||||
|
builder = self.builder.with_remover(remover)
|
||||||
|
self.assertEqual(builder._remover, remover)
|
||||||
|
|
||||||
|
def test_resolve_logger_factory_initializes_logger_factory(self):
|
||||||
|
self.builder._logger_factory = None
|
||||||
|
|
||||||
|
self.builder._resolve_logger_factory()
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.builder._logger_factory)
|
||||||
|
|
||||||
|
def test_resolve_gresource_initializes_gresource(self):
|
||||||
|
self.builder._logger_factory = Mock()
|
||||||
|
self.builder._gresource = None
|
||||||
|
|
||||||
|
self.builder._resolve_gresource()
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.builder._gresource)
|
||||||
|
|
||||||
|
def test_builder_supports_chaining(self):
|
||||||
|
theme = self.builder.with_mode("dark").with_filled(True).build()
|
||||||
|
|
||||||
|
self.assertIsNotNone(theme)
|
||||||
|
|
||||||
|
def test_resolve_ubuntu_gdm_alternatives_updater_initializes_gresource(self):
|
||||||
|
self.builder._logger_factory = Mock()
|
||||||
|
self.builder._gresource = Mock()
|
||||||
|
self.builder._ubuntu_gdm_alternatives_updater = None
|
||||||
|
self.builder._resolve_ubuntu_gdm_alternatives_updater()
|
||||||
|
self.assertIsNotNone(self.builder._ubuntu_gdm_alternatives_updater)
|
||||||
|
|
||||||
|
def test_resolve_preparer_initializes_preparer(self):
|
||||||
|
self.builder._logger_factory = Mock()
|
||||||
|
self.builder._gresource = Mock()
|
||||||
|
self.builder._ubuntu_gdm_alternatives_updater = Mock()
|
||||||
|
self.builder._preparer = None
|
||||||
|
|
||||||
|
self.builder._resolve_preparer()
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.builder._preparer)
|
||||||
|
|
||||||
|
def test_resolve_installer_initializes_installer(self):
|
||||||
|
self.builder._gresource = Mock()
|
||||||
|
self.builder._ubuntu_gdm_alternatives_updater = Mock()
|
||||||
|
self.builder._installer = None
|
||||||
|
|
||||||
|
self.builder._resolve_installer()
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.builder._installer)
|
||||||
|
|
||||||
|
def test_resolve_remover_initializes_remover(self):
|
||||||
|
self.builder._gresource = Mock()
|
||||||
|
self.builder._ubuntu_gdm_alternatives_updater = Mock()
|
||||||
|
self.builder._remover = None
|
||||||
|
|
||||||
|
self.builder._resolve_remover()
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.builder._remover)
|
||||||
|
|
||||||
|
def test_build_resolves_dependencies(self):
|
||||||
|
self.builder._resolve_logger_factory = Mock()
|
||||||
|
self.builder._resolve_gresource = Mock()
|
||||||
|
self.builder._resolve_ubuntu_gdm_alternatives_updater = Mock()
|
||||||
|
self.builder._resolve_preparer = Mock()
|
||||||
|
self.builder._resolve_installer = Mock()
|
||||||
|
self.builder._resolve_remover = Mock()
|
||||||
|
|
||||||
|
self.builder.build()
|
||||||
|
|
||||||
|
self.builder._resolve_logger_factory.assert_called_once()
|
||||||
|
self.builder._resolve_gresource.assert_called_once()
|
||||||
|
self.builder._resolve_ubuntu_gdm_alternatives_updater.assert_called_once()
|
||||||
|
self.builder._resolve_preparer.assert_called_once()
|
||||||
|
self.builder._resolve_installer.assert_called_once()
|
||||||
|
self.builder._resolve_remover.assert_called_once()
|
||||||
|
|
||||||
|
def test_build_correctly_builds_gdm_theme(self):
|
||||||
|
self.builder._preparer = Mock()
|
||||||
|
self.builder._installer = Mock()
|
||||||
|
self.builder._remover = Mock()
|
||||||
|
|
||||||
|
result = self.builder.build()
|
||||||
|
|
||||||
|
self.assertEqual(result.preparer, self.builder._preparer)
|
||||||
|
self.assertEqual(result.installer, self.builder._installer)
|
||||||
|
self.assertEqual(result.remover, self.builder._remover)
|
||||||
|
|
||||||
|
def test_build_with_explicit_dependencies_works_correctly(self):
|
||||||
|
preparer = Mock()
|
||||||
|
installer = Mock()
|
||||||
|
remover = Mock()
|
||||||
|
builder = (self.builder
|
||||||
|
.with_preparer(preparer)
|
||||||
|
.with_installer(installer)
|
||||||
|
.with_remover(remover))
|
||||||
|
|
||||||
|
result = builder.build()
|
||||||
|
|
||||||
|
self.assertEqual(result.preparer, preparer)
|
||||||
|
self.assertEqual(result.installer, installer)
|
||||||
|
self.assertEqual(result.remover, remover)
|
87
tests/utils/global_theme/test_gdm_installer.py
Normal file
87
tests/utils/global_theme/test_gdm_installer.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import os.path
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from scripts import config
|
||||||
|
from scripts.utils.global_theme.gdm_installer import GDMThemeInstaller
|
||||||
|
|
||||||
|
|
||||||
|
class GDMInstallerTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.temp_folder = os.path.join(config.temp_tests_folder, "gdm_installer")
|
||||||
|
self.gresource = MagicMock()
|
||||||
|
self.gresource.temp_folder = self.temp_folder
|
||||||
|
|
||||||
|
self.alternatives_updater = MagicMock()
|
||||||
|
|
||||||
|
self.gdm_installer = GDMThemeInstaller(
|
||||||
|
gresource=self.gresource,
|
||||||
|
alternatives_updater=self.alternatives_updater
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_is_installed_return_the_same_value_as_gresource(self):
|
||||||
|
self.gresource.has_trigger.return_value = True
|
||||||
|
|
||||||
|
result = self.gdm_installer.is_installed()
|
||||||
|
|
||||||
|
self.assertTrue(result)
|
||||||
|
self.gresource.has_trigger.assert_called_once()
|
||||||
|
|
||||||
|
def test_compile_does_not_call_label_theme_if_label_is_none(self):
|
||||||
|
theme_prepare = MagicMock()
|
||||||
|
theme_prepare.label = None
|
||||||
|
theme_prepare.label_theme = MagicMock()
|
||||||
|
|
||||||
|
self.gdm_installer.compile(themes=[theme_prepare], hue=0, color="red", sat=None)
|
||||||
|
|
||||||
|
theme_prepare.label_theme.assert_not_called()
|
||||||
|
|
||||||
|
def test_compile_calls_label_theme_if_label_is_set(self):
|
||||||
|
theme_prepare = MagicMock()
|
||||||
|
theme_prepare.label = "dark"
|
||||||
|
theme_prepare.label_theme = MagicMock()
|
||||||
|
|
||||||
|
self.gdm_installer.compile(themes=[theme_prepare], hue=0, color="red", sat=None)
|
||||||
|
|
||||||
|
theme_prepare.label_theme.assert_called_once()
|
||||||
|
|
||||||
|
def test_compile_calls_removes_keywords_and_properties_and_prepends_source_styles(self):
|
||||||
|
theme_prepare = MagicMock()
|
||||||
|
theme_prepare.remove_keywords = MagicMock()
|
||||||
|
theme_prepare.remove_properties = MagicMock()
|
||||||
|
theme_prepare.prepend_source_styles = MagicMock()
|
||||||
|
|
||||||
|
self.gdm_installer.compile(themes=[theme_prepare], hue=0, color="red", sat=None)
|
||||||
|
|
||||||
|
theme_prepare.remove_keywords.assert_called_once()
|
||||||
|
theme_prepare.remove_properties.assert_called_once()
|
||||||
|
theme_prepare.prepend_source_styles.assert_called_once()
|
||||||
|
|
||||||
|
def test_compile_installs_themes_with_correct_parameters(self):
|
||||||
|
theme_prepare = MagicMock()
|
||||||
|
theme_prepare.install = MagicMock()
|
||||||
|
themes = [theme_prepare]
|
||||||
|
hue = 0
|
||||||
|
color = "red"
|
||||||
|
sat = None
|
||||||
|
|
||||||
|
self.gdm_installer.compile(themes, hue, color, sat)
|
||||||
|
|
||||||
|
theme_prepare.install.assert_called_once()
|
||||||
|
theme_prepare.install.assert_called_with(hue, color, sat, destination=self.temp_folder)
|
||||||
|
|
||||||
|
def test_compile_calls_gresource_compile(self):
|
||||||
|
self.gdm_installer.compile([], 0, "red", None)
|
||||||
|
|
||||||
|
self.gresource.compile.assert_called_once()
|
||||||
|
|
||||||
|
def test_backup_calls_gresource_backup(self):
|
||||||
|
self.gdm_installer.backup()
|
||||||
|
|
||||||
|
self.gresource.backup.assert_called_once()
|
||||||
|
|
||||||
|
def test_install_calls_gresource_move_and_alternatives_updater_install_and_set(self):
|
||||||
|
self.gdm_installer.install()
|
||||||
|
|
||||||
|
self.gresource.move.assert_called_once()
|
||||||
|
self.alternatives_updater.install_and_set.assert_called_once()
|
124
tests/utils/global_theme/test_gdm_preparer.py
Normal file
124
tests/utils/global_theme/test_gdm_preparer.py
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
from scripts import config
|
||||||
|
from scripts.types.theme_base import ThemeBase
|
||||||
|
from scripts.utils.global_theme.gdm_preparer import GDMThemePreparer
|
||||||
|
|
||||||
|
|
||||||
|
class DummyTheme(ThemeBase):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.temp_folder = None
|
||||||
|
self.main_styles = None
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def install(self, hue: int, name: str, sat: float | None = None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestGDMThemePreparer(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.temp_folder = os.path.join(config.temp_tests_folder, "gdm_preparer")
|
||||||
|
|
||||||
|
self.gresource = self._mock_gresource(self.temp_folder)
|
||||||
|
self.theme_builder = self._mock_builder()
|
||||||
|
|
||||||
|
self.mock_logger = MagicMock()
|
||||||
|
self.logger_factory = MagicMock()
|
||||||
|
self.logger_factory.create_logger.return_value = self.mock_logger
|
||||||
|
|
||||||
|
self.preparer = GDMThemePreparer(
|
||||||
|
temp_folder=self.temp_folder,
|
||||||
|
default_mode="light",
|
||||||
|
is_filled=True,
|
||||||
|
gresource=self.gresource,
|
||||||
|
theme_builder=self.theme_builder,
|
||||||
|
logger_factory=self.logger_factory,
|
||||||
|
files_labeler_factory=MagicMock(),
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _mock_gresource(temp_folder):
|
||||||
|
gresource = MagicMock()
|
||||||
|
gresource.temp_folder = temp_folder
|
||||||
|
gresource.extract = MagicMock()
|
||||||
|
gresource.use_backup_gresource = MagicMock()
|
||||||
|
return gresource
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _mock_builder():
|
||||||
|
theme_builder = MagicMock()
|
||||||
|
theme_builder.with_temp_folder.return_value = theme_builder
|
||||||
|
theme_builder.with_theme_name.return_value = theme_builder
|
||||||
|
theme_builder.with_mode.return_value = theme_builder
|
||||||
|
theme_builder.filled.return_value = theme_builder
|
||||||
|
theme_builder.with_logger_factory.return_value = theme_builder
|
||||||
|
theme_builder.with_reset_dependencies.return_value = theme_builder
|
||||||
|
theme_builder.build.return_value = DummyTheme()
|
||||||
|
return theme_builder
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_folder, ignore_errors=True)
|
||||||
|
|
||||||
|
def test_use_backup_as_source(self):
|
||||||
|
self.preparer.use_backup_as_source()
|
||||||
|
|
||||||
|
self.gresource.use_backup_gresource.assert_called_once()
|
||||||
|
|
||||||
|
@patch("os.listdir")
|
||||||
|
def test_preparer_extracts_gresource(self, mock_listdir):
|
||||||
|
mock_listdir.return_value = ["gnome-shell.css"]
|
||||||
|
|
||||||
|
self.preparer.prepare()
|
||||||
|
|
||||||
|
self.gresource.extract.assert_called_once()
|
||||||
|
|
||||||
|
@patch("os.listdir")
|
||||||
|
def test_preparer_scans_correct_directory(self, mock_listdir):
|
||||||
|
mock_listdir.return_value = ["gnome-shell.css"]
|
||||||
|
|
||||||
|
self.preparer.prepare()
|
||||||
|
|
||||||
|
mock_listdir.assert_called_once_with(self.gresource.temp_folder)
|
||||||
|
|
||||||
|
@patch("os.listdir")
|
||||||
|
def test_preparer_filters_valid_css_files(self, mock_listdir):
|
||||||
|
valid_files = ["gnome-shell-dark.css", "gnome-shell-light.css", "gnome-shell.css"]
|
||||||
|
invalid_files = ["other.css", "readme.txt"]
|
||||||
|
mock_listdir.return_value = valid_files + invalid_files
|
||||||
|
|
||||||
|
themes = self.preparer.prepare()
|
||||||
|
|
||||||
|
self.assertEqual(len(themes), len(valid_files))
|
||||||
|
|
||||||
|
@patch("os.listdir")
|
||||||
|
def test_preparer_assigns_correct_labels(self, mock_listdir):
|
||||||
|
test_files = ["gnome-shell-dark.css", "gnome-shell-light.css", "gnome-shell.css"]
|
||||||
|
mock_listdir.return_value = test_files
|
||||||
|
|
||||||
|
themes = self.preparer.prepare()
|
||||||
|
|
||||||
|
expected_labels = {
|
||||||
|
"gnome-shell-dark.css": "dark",
|
||||||
|
"gnome-shell-light.css": "light",
|
||||||
|
"gnome-shell.css": "light" # Uses default_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
for theme_obj in themes:
|
||||||
|
file_name = os.path.basename(theme_obj.theme_file)
|
||||||
|
self.assertEqual(theme_obj.label, expected_labels[file_name])
|
||||||
|
|
||||||
|
@patch("os.listdir")
|
||||||
|
def test_preparer_configures_theme_builder_correctly(self, mock_listdir):
|
||||||
|
mock_listdir.return_value = ["gnome-shell-dark.css", "gnome-shell.css"]
|
||||||
|
|
||||||
|
self.preparer.prepare()
|
||||||
|
|
||||||
|
self.theme_builder.with_theme_name.assert_any_call("gnome-shell-dark")
|
||||||
|
self.theme_builder.with_theme_name.assert_any_call("gnome-shell")
|
||||||
|
|
44
tests/utils/global_theme/test_gdm_remover.py
Normal file
44
tests/utils/global_theme/test_gdm_remover.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from scripts.utils.global_theme.gdm_remover import GDMThemeRemover
|
||||||
|
from scripts.utils.gresource import GresourceBackupNotFoundError
|
||||||
|
|
||||||
|
|
||||||
|
class GDMRemoverTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.gresource = MagicMock()
|
||||||
|
self.alternatives_updater = MagicMock()
|
||||||
|
self.logger = MagicMock()
|
||||||
|
self.logger_factory = MagicMock(return_value=self.logger)
|
||||||
|
|
||||||
|
self.remover = GDMThemeRemover(
|
||||||
|
gresource=self.gresource,
|
||||||
|
alternatives_updater=self.alternatives_updater,
|
||||||
|
logger_factory=self.logger_factory
|
||||||
|
)
|
||||||
|
|
||||||
|
self.remover.remover_logger = MagicMock()
|
||||||
|
|
||||||
|
def test_remove_logs_start_message(self):
|
||||||
|
self.remover.remove()
|
||||||
|
|
||||||
|
self.remover.remover_logger.start_removing.assert_called_once()
|
||||||
|
|
||||||
|
def test_remove_calls_gresource_restore_and_alternatives_remove(self):
|
||||||
|
self.remover.remove()
|
||||||
|
|
||||||
|
self.gresource.restore.assert_called_once()
|
||||||
|
self.alternatives_updater.remove.assert_called_once()
|
||||||
|
|
||||||
|
def test_remove_logs_success_message(self):
|
||||||
|
self.remover.remove()
|
||||||
|
|
||||||
|
self.remover.remover_logger.success_removing.assert_called_once()
|
||||||
|
|
||||||
|
def test_remove_logs_error_message_when_backup_not_found(self):
|
||||||
|
self.gresource.restore.side_effect = GresourceBackupNotFoundError()
|
||||||
|
|
||||||
|
self.remover.remove()
|
||||||
|
|
||||||
|
self.remover.remover_logger.error_removing.assert_called_once()
|
118
tests/utils/global_theme/test_gdm_theme_prepare.py
Normal file
118
tests/utils/global_theme/test_gdm_theme_prepare.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import os.path
|
||||||
|
import shutil
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from scripts import config
|
||||||
|
from scripts.utils.global_theme.gdm_theme_prepare import GDMThemePrepare
|
||||||
|
from ..._helpers import create_dummy_file, try_remove_file
|
||||||
|
|
||||||
|
|
||||||
|
class GDMThemePrepareTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.temp_folder = os.path.join(config.temp_tests_folder, "gdm_theme_prepare")
|
||||||
|
self.main_styles = os.path.join(self.temp_folder, "gnome-shell.css")
|
||||||
|
self.theme = MagicMock()
|
||||||
|
self.theme.add_to_start.return_value = None
|
||||||
|
self.theme.temp_folder = self.temp_folder
|
||||||
|
self.theme.main_styles = self.main_styles
|
||||||
|
|
||||||
|
self.main_styles_destination = os.path.join(self.temp_folder, "gnome-shell-result.css")
|
||||||
|
create_dummy_file(self.main_styles_destination, "body { background-color: #000; }")
|
||||||
|
|
||||||
|
self.files_labeler = MagicMock()
|
||||||
|
|
||||||
|
self.theme_prepare = GDMThemePrepare(
|
||||||
|
theme=self.theme,
|
||||||
|
theme_file=self.main_styles_destination,
|
||||||
|
label=None,
|
||||||
|
files_labeler=self.files_labeler,
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_folder, ignore_errors=True)
|
||||||
|
|
||||||
|
def test_label_files_calls_labeler(self):
|
||||||
|
self.theme_prepare.label = "dark"
|
||||||
|
|
||||||
|
self.theme_prepare.label_theme()
|
||||||
|
|
||||||
|
self.files_labeler.append_label.assert_called_once_with("dark")
|
||||||
|
|
||||||
|
def test_label_files_raises_value_error_if_label_none(self):
|
||||||
|
self.theme_prepare.label = None
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.theme_prepare.label_theme()
|
||||||
|
|
||||||
|
def test_remove_keywords_removes_destination_keywords(self):
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
expected_content = "body { background-color: #000; }"
|
||||||
|
create_dummy_file(self.main_styles_destination, "body {keyword1 background-color: #000 !important; }")
|
||||||
|
keywords = ["keyword1", " !important"]
|
||||||
|
|
||||||
|
self.theme_prepare.remove_keywords(*keywords)
|
||||||
|
|
||||||
|
with open(self.main_styles_destination, 'r') as file:
|
||||||
|
content = file.read()
|
||||||
|
self.assertEqual(content, expected_content)
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
|
||||||
|
def test_remove_properties_removes_destination_properties(self):
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
expected_content = "body {\n}\n"
|
||||||
|
create_dummy_file(self.main_styles_destination, "body {\nbackground-color: #000;\n}")
|
||||||
|
properties = ["background-color"]
|
||||||
|
|
||||||
|
self.theme_prepare.remove_properties(*properties)
|
||||||
|
|
||||||
|
with open(self.main_styles_destination, 'r') as file:
|
||||||
|
actual_content = file.read()
|
||||||
|
self.assertEqual(expected_content, actual_content)
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
|
||||||
|
def test_remove_properties_removes_one_line_properties(self):
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
expected_content = ""
|
||||||
|
create_dummy_file(self.main_styles_destination, "body { background-color: #000; }")
|
||||||
|
properties = ["background-color"]
|
||||||
|
|
||||||
|
self.theme_prepare.remove_properties(*properties)
|
||||||
|
|
||||||
|
with open(self.main_styles_destination, 'r') as file:
|
||||||
|
actual_content = file.read()
|
||||||
|
self.assertEqual(expected_content, actual_content)
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
|
||||||
|
def test_prepend_source_styles_prepends_destination_styles(self):
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
expected_content = "body { background-color: #000; }\n"
|
||||||
|
create_dummy_file(self.main_styles_destination, "body { background-color: #000; }")
|
||||||
|
|
||||||
|
self.theme_prepare.prepend_source_styles("")
|
||||||
|
|
||||||
|
called_content: str = self.theme.add_to_start.call_args[0][0]
|
||||||
|
self.assertTrue(called_content.startswith(expected_content))
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
|
||||||
|
def test_prepend_source_styles_adds_trigger(self):
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
expected_content = "\ntrigger\n"
|
||||||
|
create_dummy_file(self.main_styles_destination)
|
||||||
|
trigger = "trigger"
|
||||||
|
|
||||||
|
self.theme_prepare.prepend_source_styles(trigger)
|
||||||
|
|
||||||
|
called_content: str = self.theme.add_to_start.call_args[0][0]
|
||||||
|
self.assertTrue(expected_content in called_content)
|
||||||
|
try_remove_file(self.main_styles_destination)
|
||||||
|
|
||||||
|
def test_install_passes_arguments_to_theme(self):
|
||||||
|
hue = 0
|
||||||
|
color = "#000000"
|
||||||
|
sat = 100
|
||||||
|
destination = os.path.join(self.temp_folder, "destination")
|
||||||
|
|
||||||
|
self.theme_prepare.install(hue, color, sat, destination)
|
||||||
|
|
||||||
|
self.theme.install.assert_called_once_with(hue, color, sat, destination=destination)
|
@@ -0,0 +1,47 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from scripts.utils.alternatives_updater import AlternativesUpdater
|
||||||
|
from scripts.utils.global_theme.ubuntu_alternatives_updater import UbuntuGDMAlternativesUpdater
|
||||||
|
|
||||||
|
|
||||||
|
class UbuntuGDMUpdateAlternativesTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.updater = MagicMock(spec=AlternativesUpdater)
|
||||||
|
self.ubuntu_updater = UbuntuGDMAlternativesUpdater(
|
||||||
|
alternatives_updater=self.updater
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_custom_destination_updates_correctly(self):
|
||||||
|
custom_destination_dir = "/custom/path"
|
||||||
|
custom_destination_file = "custom_file.gresource"
|
||||||
|
|
||||||
|
self.ubuntu_updater.with_custom_destination(
|
||||||
|
custom_destination_dir, custom_destination_file
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.ubuntu_updater.destination_dir, custom_destination_dir
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.ubuntu_updater.destination_file, custom_destination_file
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_install_and_set_calls_updater_correctly(self):
|
||||||
|
priority = 100
|
||||||
|
self.ubuntu_updater.install_and_set(priority)
|
||||||
|
|
||||||
|
self.updater.install_and_set.assert_called_once_with(
|
||||||
|
link=self.ubuntu_updater.ubuntu_gresource_path,
|
||||||
|
name=self.ubuntu_updater.ubuntu_gresource_link_name,
|
||||||
|
path=self.ubuntu_updater.gnome_gresource_path,
|
||||||
|
priority=priority
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_remove_calls_updater_correctly(self):
|
||||||
|
self.ubuntu_updater.remove()
|
||||||
|
|
||||||
|
self.updater.remove.assert_called_once_with(
|
||||||
|
name=self.ubuntu_updater.ubuntu_gresource_link_name,
|
||||||
|
path=self.ubuntu_updater.gnome_gresource_path
|
||||||
|
)
|
57
tests/utils/test_files_labeler.py
Normal file
57
tests/utils/test_files_labeler.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import os.path
|
||||||
|
import shutil
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from scripts import config
|
||||||
|
from scripts.utils.files_labeler import FilesLabelerFactoryImpl
|
||||||
|
from .._helpers import create_dummy_file
|
||||||
|
|
||||||
|
|
||||||
|
class FilesLabelerTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.temp_folder = os.path.join(config.temp_tests_folder, "labeler")
|
||||||
|
|
||||||
|
self.files = ["file1.svg", "file2.png", "file3.svg"]
|
||||||
|
self.styles_file = os.path.join(self.temp_folder, "styles-test.css") # styles files are already labeled
|
||||||
|
self.original_styles_content = f"body {{ background: url('./{self.files[0]}'); }}"
|
||||||
|
|
||||||
|
self.factory = FilesLabelerFactoryImpl()
|
||||||
|
|
||||||
|
def _generate_test_files(self):
|
||||||
|
self.tearDown()
|
||||||
|
|
||||||
|
for filename in self.files:
|
||||||
|
create_dummy_file(os.path.join(self.temp_folder, filename))
|
||||||
|
|
||||||
|
create_dummy_file(self.styles_file, self.original_styles_content)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_folder, ignore_errors=True)
|
||||||
|
|
||||||
|
def test_append_label_correctly_labels_files(self):
|
||||||
|
self._generate_test_files()
|
||||||
|
label = "test"
|
||||||
|
labeled_files = [(f, f.replace(".", f"-{label}.")) for f in self.files]
|
||||||
|
labeler = self.factory.create(self.temp_folder)
|
||||||
|
|
||||||
|
labeler.append_label(label)
|
||||||
|
|
||||||
|
for original, labeled in labeled_files:
|
||||||
|
labeled_path = os.path.join(self.temp_folder, labeled)
|
||||||
|
original_path = os.path.join(self.temp_folder, original)
|
||||||
|
self.assertTrue(os.path.exists(labeled_path))
|
||||||
|
self.assertFalse(os.path.exists(original_path))
|
||||||
|
|
||||||
|
def test_append_label_correctly_updates_references(self):
|
||||||
|
self._generate_test_files()
|
||||||
|
label = "test"
|
||||||
|
replaced_file = self.files[0].replace('.', f'-{label}.')
|
||||||
|
expected_content = f"body {{ background: url('./{replaced_file}'); }}"
|
||||||
|
labeler = self.factory.create(self.temp_folder, self.styles_file)
|
||||||
|
|
||||||
|
labeler.append_label(label)
|
||||||
|
|
||||||
|
with open(self.styles_file, 'r') as file:
|
||||||
|
actual_content = file.read()
|
||||||
|
self.assertNotEqual(actual_content, self.original_styles_content)
|
||||||
|
self.assertEqual(actual_content, expected_content)
|
Reference in New Issue
Block a user