From fc316fd2d4fc4c13b5d704177fcae151eb352b45 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sat, 24 Oct 2020 19:11:35 +0200 Subject: [PATCH] BaseUtils: added color helper + unit tests --- .../TheCodeLabs_BaseUtils/Color.py | 38 +++++++++++++ .../TheCodeLabs_BaseUtils/__init__.py | 4 -- TheCodeLabs_BaseUtils/__init__.py | 0 TheCodeLabs_BaseUtils/test/ColorTest.py | 54 +++++++++++++++++++ TheCodeLabs_BaseUtils/test/__init__.py | 0 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/Color.py create mode 100644 TheCodeLabs_BaseUtils/__init__.py create mode 100644 TheCodeLabs_BaseUtils/test/ColorTest.py create mode 100644 TheCodeLabs_BaseUtils/test/__init__.py diff --git a/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/Color.py b/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/Color.py new file mode 100644 index 0000000..a720fac --- /dev/null +++ b/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/Color.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass +class Color: + red: int + green: int + blue: int + opacity: float = 1.0 + + @staticmethod + def from_hex(hexString: str) -> Color: + hexString = hexString.lstrip('#') + if len(hexString) == 3: + parts = [int(f'{hexString[i:i + 1]}{hexString[i:i + 1]}', 16) for i in range(0, 3)] + elif len(hexString) == 6: + parts = [int(hexString[i:i + 2], 16) for i in (0, 2, 4)] + elif len(hexString) == 8: + parts = [int(hexString[i:i + 2], 16) for i in (0, 2, 4, 6)] + else: + raise ValueError('Provided hex string has invalid format!') + + return Color(parts[0], parts[1], parts[2], (parts[3] / 255.0) if len(parts) == 4 else 1.0) + + def to_hex(self) -> str: + opacity = int(self.opacity * 255) + return '#{:02X}{:02X}{:02X}{:02X}'.format(self.red, self.green, self.blue, opacity) + + def to_hex_without_opacity(self) -> str: + return '#{:02X}{:02X}{:02X}'.format(self.red, self.green, self.blue) + + def to_rgba(self) -> str: + return f'rgba({self.red}, {self.green}, {self.blue}, {self.opacity})' + + def to_rgb(self) -> str: + return f'rgb({self.red}, {self.green}, {self.blue})' diff --git a/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/__init__.py b/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/__init__.py index 1e65e41..e69de29 100644 --- a/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/__init__.py +++ b/TheCodeLabs_BaseUtils/TheCodeLabs_BaseUtils/__init__.py @@ -1,4 +0,0 @@ -from TheCodeLabs_BaseUtils.DefaultLogger import DefaultLogger -from TheCodeLabs_BaseUtils.MailHandler import MailHandler -from TheCodeLabs_BaseUtils.CachedService import CachedService -import TheCodeLabs_BaseUtils.OverrideDecorator diff --git a/TheCodeLabs_BaseUtils/__init__.py b/TheCodeLabs_BaseUtils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TheCodeLabs_BaseUtils/test/ColorTest.py b/TheCodeLabs_BaseUtils/test/ColorTest.py new file mode 100644 index 0000000..23828cb --- /dev/null +++ b/TheCodeLabs_BaseUtils/test/ColorTest.py @@ -0,0 +1,54 @@ +import unittest + +from TheCodeLabs_BaseUtils.TheCodeLabs_BaseUtils.Color import Color + + +class ColorTest(unittest.TestCase): + def test_to_hex(self): + color = Color(255, 0, 0) + self.assertEqual('#FF0000FF', color.to_hex()) + + def test_to_hex_without_opacity(self): + color = Color(255, 0, 0) + self.assertEqual('#FF0000', color.to_hex_without_opacity()) + + def test_to_rgba(self): + color = Color(255, 0, 0) + self.assertEqual('rgba(255, 0, 0, 1.0)', color.to_rgba()) + + def test_to_rgb(self): + color = Color(255, 0, 0) + self.assertEqual('rgb(255, 0, 0)', color.to_rgb()) + + def test_from_hex_normal(self): + hexString = '#FF0000' + color = Color.from_hex(hexString) + self.assertEqual(255, color.red) + self.assertEqual(0, color.green) + self.assertEqual(0, color.blue) + self.assertAlmostEqual(1.0, color.opacity, 2) + + def test_from_hex_with_opacity(self): + hexString = '#FF000080' + color = Color.from_hex(hexString) + self.assertEqual(255, color.red) + self.assertEqual(0, color.green) + self.assertEqual(0, color.blue) + self.assertAlmostEqual(0.5, color.opacity, 2) + + def test_from_hex_short(self): + hexString = '#F0F' + color = Color.from_hex(hexString) + self.assertEqual(255, color.red) + self.assertEqual(0, color.green) + self.assertEqual(255, color.blue) + self.assertAlmostEqual(1.0, color.opacity, 2) + + def test_from_invalid(self): + hexString = '#12345' + with self.assertRaises(ValueError): + Color.from_hex(hexString) + + +if __name__ == '__main__': + unittest.main() diff --git a/TheCodeLabs_BaseUtils/test/__init__.py b/TheCodeLabs_BaseUtils/test/__init__.py new file mode 100644 index 0000000..e69de29 -- GitLab