diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml new file mode 100644 index 0000000..37ef547 --- /dev/null +++ b/.github/workflows/coverage.yaml @@ -0,0 +1,37 @@ +name: Coverage + +on: [push] + +jobs: + coverage: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.14 + uses: actions/setup-python@v4 + with: + python-version: 3.14 + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + python -m pip install coverage pytest pytest-asyncio + if [ -f requirements.txt ]; then python -m pip install -r requirements.txt; fi + - name: Run Coverage + run: | + export PYTHONPATH=./src + coverage run -m pytest tests + - name: Generate Coverage Report + run: | + coverage report -m + coverage xml + - name: Creating coverage folder + run: | + mkdir -p coverage + pip install -U genbadge defusedxml + genbadge coverage -i coverage.xml -o coverage/coverage.svg + - name: Publish coverage report to coverage-badge branch + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: coverage-badge + folder: coverage diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..4288fd0 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,27 @@ +name: Tests + +on: [push] + +jobs: + unittests: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + python -m pip install pytest pytest-asyncio + if [ -f requirements.txt ]; then python -m pip install -r requirements.txt; fi + - name: Run Unittests + run: | + export PYTHONPATH=./src + pytest -v tests diff --git a/examples/images/color-gradient-example.gif b/examples/images/color-gradient-example.gif new file mode 100644 index 0000000..cb6bc4c Binary files /dev/null and b/examples/images/color-gradient-example.gif differ diff --git a/examples/images/simple.png b/examples/images/simple.png new file mode 100644 index 0000000..0c4d90b Binary files /dev/null and b/examples/images/simple.png differ diff --git a/pyproject.toml b/pyproject.toml index f9f7324..9e1a24d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ dev = [ "pytest", "pytest-asyncio", "coverage", + "textual-thin-slider", ] [project.urls] diff --git a/requirements.txt b/requirements.txt index 27a033a..f15ce1b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ textual # pytest # pytest-asyncio # coverage +# textual-thin-slider diff --git a/src/textual_color_gradient/__init__.py b/src/textual_color_gradient/__init__.py index d2c1015..9176734 100644 --- a/src/textual_color_gradient/__init__.py +++ b/src/textual_color_gradient/__init__.py @@ -4,10 +4,9 @@ # from .color_gradient import ColorGradient, ColorGradientRenderer, GRADIENT_RANGE_MAX, GRADIENT_RANGE_MIN - __all__ = [ - ColorGradient, - ColorGradientRenderer, - GRADIENT_RANGE_MAX, - GRADIENT_RANGE_MIN, + "ColorGradient", + "ColorGradientRenderer", + "GRADIENT_RANGE_MAX", + "GRADIENT_RANGE_MIN", ] \ No newline at end of file diff --git a/src/textual_color_gradient/color_gradient.py b/src/textual_color_gradient/color_gradient.py index bcd0694..b647354 100644 --- a/src/textual_color_gradient/color_gradient.py +++ b/src/textual_color_gradient/color_gradient.py @@ -4,7 +4,7 @@ # import colorsys from math import ceil -from typing import ClassVar, Any, Type +from typing import ClassVar, Any, Type, Union, List from rich.color import Color as RichColor from rich.segment import Segment @@ -42,7 +42,7 @@ def _hsv_to_rgb(cls, hue: int, sat: int, val: int) -> tuple: )) @classmethod - def _gradient_gen(cls, y: int, hue: int, sat: int, val: int, width: int, height: int, target: bool) -> list[Any]: + def _gradient_gen(cls, y: int, hue: int, sat: int, val: int, width: int, height: int, target: bool) -> List[Any]: """ Calculate the H, S and V values for each cell of the gradient square """ horz_step = GRADIENT_RANGE_MAX / width vert_step = GRADIENT_RANGE_MAX / height @@ -72,7 +72,7 @@ def _gradient_gen(cls, y: int, hue: int, sat: int, val: int, width: int, height: ) return segments - def render_line_segment(self, hsv: HSV, y: int, width: int, height: int, target: bool = True) -> list[Segment]: + def render_line_segment(self, hsv: HSV, y: int, width: int, height: int, target: bool = True) -> List[Segment]: return self._gradient_gen( y, round(hsv.h * GRADIENT_RANGE_MAX), @@ -108,26 +108,26 @@ def watch_value(self) -> None: self.post_message(self.Changed(self, self.value)) def to_color(self) -> Color: - return Color.from_hsv(self.value) + return Color.from_hsv(*self.value) class Changed(Message): """ Posted when the value of the gradient changes. This message can be handled using an `on_gradient_changed` method. """ - def __init__(self, color_manager: ColorGradient, hsv: HSV) -> None: + def __init__(self, color_manager: "ColorGradient", hsv: HSV) -> None: super().__init__() self.hsv = hsv - self.__control__: ColorGradient = color_manager + self.__control__: "ColorGradient" = color_manager @property - def control(self) -> ColorGradient: + def control(self) -> "ColorGradient": return self.__control__ # -- ------------------------------------------------------------ - def __init__(self, value: HSV | None = None, name: str | None = None, id: str | None = None, - classes: str | None = None, disabled: bool = False) -> None: + def __init__(self, value: Union[HSV, None] = None, name: Union[str, None] = None, id: Union[str, None] = None, + classes: Union[str, None] = None, disabled: bool = False) -> None: super().__init__(name=name, id=id, classes=classes, disabled=disabled, markup=False) self.value = value if value is not None else HSV(*_INITIAL_HSV) self.renderer = ColorGradientRenderer() diff --git a/tests/test_gradient_renderer.py b/tests/test_gradient_renderer.py index 4f77d2a..7cb5b5b 100644 --- a/tests/test_gradient_renderer.py +++ b/tests/test_gradient_renderer.py @@ -2,10 +2,8 @@ # This file is subject to the terms and conditions defined in the # file 'LICENSE', which is part of this source code package. # -import colorsys -from textual.color import HSV, Color -from src.textual_color_gradient.color_gradient import (ColorGradient, ColorGradientRenderer, GRADIENT_RANGE_MIN, - GRADIENT_RANGE_MAX) +from textual.color import HSV +from src.textual_color_gradient.color_gradient import ColorGradientRenderer, GRADIENT_RANGE_MIN, GRADIENT_RANGE_MAX TEST_HSV = (0.0, 121 / GRADIENT_RANGE_MAX, 131 / GRADIENT_RANGE_MAX)