From 2c7b8b3cfaa7b3f5bbbb258d16d2dace9a6dbeee Mon Sep 17 00:00:00 2001 From: "K.-Michael Aye" <69774+michaelaye@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:02:37 +0100 Subject: [PATCH] Improve error handling and add test cases for file_variations and datetime functionality in planetarypy. --- src/planetarypy/utils.py | 12 +++++++++++- tests/test_datetime.py | 37 +++++++++++++++++++++++++++++++++++++ tests/test_planetarypy.py | 30 +++++++++++++++++++----------- tests/test_utils.py | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/planetarypy/utils.py b/src/planetarypy/utils.py index 9315bed..ab03098 100644 --- a/src/planetarypy/utils.py +++ b/src/planetarypy/utils.py @@ -140,9 +140,19 @@ def file_variations(filename: Union[str, Path], extensions: list) -> list: Parameters ---------- - filename : str + filename : str or Path The original filename to use as a base. extensions : list List of extensions to use for variations. + + Raises + ------ + TypeError + If extensions is not a list + ValueError + If any extension doesn't start with a dot """ + if not isinstance(extensions, list): + raise TypeError("extensions must be a list") + return [Path(filename).with_suffix(extension) for extension in extensions] diff --git a/tests/test_datetime.py b/tests/test_datetime.py index b36113e..0fec64a 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -73,6 +73,26 @@ def test_variations(self): ppydt.fromdoyformat(ordinal_datetime_with_ms), ) + def test_fromdoyformat_invalid_format(self): + invalid_formats = [ + "2024/127T11:15:00", # Wrong separator + "2024-367T11:15:00", # Invalid day of year + "2024-000T11:15:00", # Day of year can't be 0 + "abcd-123T11:15:00", # Invalid year + ] + for invalid_format in invalid_formats: + with self.assertRaises(ValueError): + ppydt.fromdoyformat(invalid_format) + + def test_doyformat_edge_cases(self): + # Test first day of year + dt = datetime.datetime(2024, 1, 1, 0, 0, 0) + self.assertEqual(ppydt.doyformat(dt), "2024-001T00:00:00") + + # Test last day of year + dt = datetime.datetime(2024, 12, 31, 23, 59, 59) + self.assertEqual(ppydt.doyformat(dt), "2024-366T23:59:59") # 2024 is leap year + class TestIsoZ(unittest.TestCase): def test_fromisozformat(self): @@ -88,3 +108,20 @@ def test_isozformat(self): no_tz = dt.replace(tzinfo=None) self.assertRaises(ValueError, ppydt.isozformat, no_tz) + + def test_fromisozformat_with_microseconds(self): + dt = datetime.datetime(2022, 10, 1, 13, 20, 0, 123456, + tzinfo=datetime.timezone.utc) + self.assertEqual(dt, + ppydt.fromisozformat("2022-10-01T13:20:00.123456Z")) + + def test_fromisozformat_invalid_formats(self): + invalid_formats = [ + "2022-10-01T13:20:00+00:00", # Wrong timezone format + "2022-10-01 13:20:00Z", # Missing T + "2022-13-01T13:20:00Z", # Invalid month + "2022-10-32T13:20:00Z", # Invalid day + ] + for invalid_format in invalid_formats: + with self.assertRaises(ValueError): + ppydt.fromisozformat(invalid_format) diff --git a/tests/test_planetarypy.py b/tests/test_planetarypy.py index e02971b..1f65d25 100644 --- a/tests/test_planetarypy.py +++ b/tests/test_planetarypy.py @@ -3,22 +3,30 @@ """Tests for `planetarypy` package.""" import pytest - - from planetarypy import planetarypy -@pytest.fixture -def response(): - """Sample pytest fixture. +def test_package_imports(): + """Test that main package components are importable.""" + from planetarypy import utils + from planetarypy import config + from planetarypy import datetime - See more at: http://doc.pytest.org/en/latest/fixture.html - """ - # import requests - # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') +def test_version(): + """Test that version string exists.""" + from planetarypy import __version__ + assert isinstance(__version__, str) + assert len(__version__) > 0 +def test_package_metadata(): + """Test package metadata.""" + from planetarypy import __author__ + from planetarypy import __email__ + assert isinstance(__author__, str) + assert isinstance(__email__, str) + assert '@' in __email__ +@pytest.mark.skip(reason="Template test - implement actual functionality") def test_content(response): """Sample pytest test function with the pytest fixture as an argument.""" - # from bs4 import BeautifulSoup - # assert 'GitHub' in BeautifulSoup(response.content).title.string + pass diff --git a/tests/test_utils.py b/tests/test_utils.py index c1d595b..6900704 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,7 @@ """Tests for utils module.""" from pathlib import Path +import pytest from planetarypy import utils @@ -16,3 +17,38 @@ def test_file_variations(): Path("abc.cal.cub"), Path("abc.map.cal.cub"), } + +def test_file_variations_with_path(): + fname = Path("/path/to/abc.txt") + extensions = [".cub", ".cal.cub"] + variations = utils.file_variations(fname, extensions) + assert len(variations) == len(extensions) + assert set(variations) == { + Path("/path/to/abc.cub"), + Path("/path/to/abc.cal.cub"), + } + +def test_file_variations_empty_extensions(): + fname = "abc.txt" + extensions = [] + variations = utils.file_variations(fname, extensions) + assert len(variations) == 0 + assert variations == [] + +def test_file_variations_invalid_extension(): + fname = "abc.txt" + extensions = ["cub"] # Missing dot prefix + with pytest.raises(ValueError): + utils.file_variations(fname, extensions) + +def test_file_variations_non_list(): + fname = "abc.txt" + invalid_inputs = [ + None, + 42, + {"ext": ".cub"}, + ".cub", # Single string instead of list + ] + for invalid_input in invalid_inputs: + with pytest.raises((TypeError, AttributeError)): + utils.file_variations(fname, invalid_input)