From b12cb420232f4186357faae801af8fcd8f4dc77e Mon Sep 17 00:00:00 2001 From: Daizu Date: Mon, 11 Aug 2025 07:08:45 +0900 Subject: [PATCH 1/3] gantt.py: Refactor date_index and GanttFrame initialization to use keyword arguments for clarity test_gantt.py: Update GanttChart instantiation to match new parameter order test_gantt_unit.py: Revise date_index tests to use keyword arguments for consistency --- src/pptxlib/contrib/gantt.py | 10 ++--- tests/contrib/gannt.py | 2 +- tests/contrib/test_gantt.py | 57 +--------------------------- tests/contrib/test_gantt_unit.py | 65 ++++++++++++++++++++++++++++++-- 4 files changed, 68 insertions(+), 66 deletions(-) diff --git a/src/pptxlib/contrib/gantt.py b/src/pptxlib/contrib/gantt.py index c48077d..b6c3854 100644 --- a/src/pptxlib/contrib/gantt.py +++ b/src/pptxlib/contrib/gantt.py @@ -13,7 +13,7 @@ from pptxlib.table import Table -def date_index(kind: str, start: datetime, end: datetime) -> list[datetime]: +def date_index(start: datetime, end: datetime, kind: str = "week") -> list[datetime]: if kind in ["month", "monthly"]: start = datetime(start.year, start.month, 1) end = datetime(end.year, end.month, 1) @@ -53,8 +53,8 @@ class GanttFrame: date_index: list[datetime] columns: list[list[str]] - def __init__(self, kind: str, start: datetime, end: datetime) -> None: - self.date_index = date_index(kind, start, end) + def __init__(self, start: datetime, end: datetime, kind: str = "week") -> None: + self.date_index = date_index(start, end, kind=kind) years = [fiscal_year(date) for date in self.date_index] months = [str(date.month) for date in self.date_index] @@ -91,15 +91,15 @@ class GanttChart: def __init__( self, - kind: str, start: datetime | str, end: datetime | str, + kind: str = "week", ) -> None: if isinstance(start, str): start = strptime(start) if isinstance(end, str): end = strptime(end) - self.frame = GanttFrame(kind, start, end) + self.frame = GanttFrame(start, end, kind=kind) def add_table( self, diff --git a/tests/contrib/gannt.py b/tests/contrib/gannt.py index e8a10ce..7aff3c0 100644 --- a/tests/contrib/gannt.py +++ b/tests/contrib/gannt.py @@ -11,7 +11,7 @@ def main(): app.presentations.close() prs = app.presentations.add() slide = prs.slides.add(layout="Blank") - gantt = GanttChart("week", datetime(2025, 5, 21), datetime(2025, 6, 10)) + gantt = GanttChart(datetime(2025, 5, 21), datetime(2025, 6, 10), kind="week") layout = prs.layouts.add(gantt.frame.name, slide) gantt.add_table(layout, 20, 50, bottom=20) slide.layout = layout diff --git a/tests/contrib/test_gantt.py b/tests/contrib/test_gantt.py index 02b1193..3d84ced 100644 --- a/tests/contrib/test_gantt.py +++ b/tests/contrib/test_gantt.py @@ -12,65 +12,10 @@ ) -def test_date_index_month(): - from pptxlib.contrib.gantt import date_index - - index = date_index("month", datetime(2024, 4, 1), datetime(2025, 9, 10)) - assert len(index) == 18 - assert index[0] == datetime(2024, 4, 1) - assert index[-1] == datetime(2025, 9, 1) - - -def test_date_index_week(): - from pptxlib.contrib.gantt import date_index - - index = date_index("week", datetime(2025, 5, 7), datetime(2025, 6, 10)) - assert len(index) == 6 - assert index[0] == datetime(2025, 5, 5) - assert index[-1] == datetime(2025, 6, 9) - - -def test_date_index_day(): - from pptxlib.contrib.gantt import date_index - - index = date_index("day", datetime(2025, 5, 7), datetime(2025, 5, 14)) - assert len(index) == 8 - assert index[0] == datetime(2025, 5, 7) - assert index[-1] == datetime(2025, 5, 14) - - -def test_date_index_error(): - from pptxlib.contrib.gantt import date_index - - with pytest.raises(ValueError): - date_index("invalid", datetime(2025, 5, 7), datetime(2025, 5, 14)) - - -def test_name_month(): - from pptxlib.contrib.gantt import GanttFrame - - gantt = GanttFrame("month", datetime(2024, 4, 1), datetime(2025, 9, 10)) - assert gantt.name == "2024/04/01-2025/09/01-month" - - -def test_name_week(): - from pptxlib.contrib.gantt import GanttFrame - - gantt = GanttFrame("week", datetime(2025, 4, 1), datetime(2025, 9, 10)) - assert gantt.name == "2025/03/31-2025/09/08-week" - - -def test_name_day(): - from pptxlib.contrib.gantt import GanttFrame - - gantt = GanttFrame("day", datetime(2025, 4, 1), datetime(2025, 9, 10)) - assert gantt.name == "2025/04/01-2025/09/10-day" - - @pytest.fixture(scope="module") def gantt(prs: Presentations): pr = prs.add(with_window=False) - gantt = GanttChart("week", "2025/5/21", "2025/6/10") + gantt = GanttChart("2025/5/21", "2025/6/10", kind="week") slide = pr.slides.add() gantt.add_table(slide, 20, 150) yield gantt diff --git a/tests/contrib/test_gantt_unit.py b/tests/contrib/test_gantt_unit.py index 356b12b..42f9c2d 100644 --- a/tests/contrib/test_gantt_unit.py +++ b/tests/contrib/test_gantt_unit.py @@ -1,24 +1,60 @@ from datetime import datetime +import pytest + from pptxlib.contrib.gantt import GanttFrame, date_index, fiscal_year +def test_date_index_month(): + from pptxlib.contrib.gantt import date_index + + index = date_index(datetime(2024, 4, 1), datetime(2025, 9, 10), kind="month") + assert len(index) == 18 + assert index[0] == datetime(2024, 4, 1) + assert index[-1] == datetime(2025, 9, 1) + + +def test_date_index_week(): + from pptxlib.contrib.gantt import date_index + + index = date_index(datetime(2025, 5, 7), datetime(2025, 6, 10), kind="week") + assert len(index) == 6 + assert index[0] == datetime(2025, 5, 5) + assert index[-1] == datetime(2025, 6, 9) + + +def test_date_index_day(): + from pptxlib.contrib.gantt import date_index + + index = date_index(datetime(2025, 5, 7), datetime(2025, 5, 14), kind="day") + assert len(index) == 8 + assert index[0] == datetime(2025, 5, 7) + assert index[-1] == datetime(2025, 5, 14) + + +def test_date_index_error(): + from pptxlib.contrib.gantt import date_index + + with pytest.raises(ValueError): + date_index(datetime(2025, 5, 7), datetime(2025, 5, 14), kind="invalid") + + def test_date_index_month_unit(): - index = date_index("month", datetime(2024, 4, 10), datetime(2025, 9, 10)) + index = date_index(datetime(2024, 4, 10), datetime(2025, 9, 10), kind="month") assert len(index) == 18 assert index[0] == datetime(2024, 4, 1) assert index[-1] == datetime(2025, 9, 1) def test_date_index_week_unit(): - index = date_index("week", datetime(2025, 5, 7), datetime(2025, 6, 10)) + index = date_index(datetime(2025, 5, 7), datetime(2025, 6, 10), kind="week") assert len(index) == 6 assert index[0] == datetime(2025, 5, 5) assert index[-1] == datetime(2025, 6, 9) def test_date_index_day_unit(): - index = date_index("day", datetime(2025, 5, 7), datetime(2025, 5, 14)) + index = date_index(datetime(2025, 5, 7), datetime(2025, 5, 14), kind="day") assert len(index) == 8 assert index[0] == datetime(2025, 5, 7) assert index[-1] == datetime(2025, 5, 14) @@ -30,5 +66,26 @@ def test_fiscal_year(): def test_ganttframe_name(): - gf = GanttFrame("week", datetime(2025, 4, 1), datetime(2025, 9, 10)) + gf = GanttFrame(datetime(2025, 4, 1), datetime(2025, 9, 10), kind="week") assert gf.name == "2025/03/31-2025/09/08-week" + + +def test_name_month(): + from pptxlib.contrib.gantt import GanttFrame + + gantt = GanttFrame(datetime(2024, 4, 1), datetime(2025, 9, 10), kind="month") + assert gantt.name == "2024/04/01-2025/09/01-month" + + +def test_name_week(): + from pptxlib.contrib.gantt import GanttFrame + + gantt = GanttFrame(datetime(2025, 4, 1), datetime(2025, 9, 10), kind="week") + assert gantt.name == "2025/03/31-2025/09/08-week" + + +def test_name_day(): + from pptxlib.contrib.gantt import GanttFrame + + gantt = GanttFrame(datetime(2025, 4, 1), datetime(2025, 9, 10), kind="day") + assert gantt.name == "2025/04/01-2025/09/10-day" From c10df529c831829a6799cc17820caab060657448 Mon Sep 17 00:00:00 2001 From: Daizu Date: Mon, 11 Aug 2025 07:11:30 +0900 Subject: [PATCH 2/3] test: Add strptime tests for date parsing and validation --- tests/contrib/test_gantt.py | 24 ------------------------ tests/contrib/test_gantt_unit.py | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/contrib/test_gantt.py b/tests/contrib/test_gantt.py index 3d84ced..cf5cad0 100644 --- a/tests/contrib/test_gantt.py +++ b/tests/contrib/test_gantt.py @@ -39,27 +39,3 @@ def test_add_str(gantt: GanttChart): s1 = gantt.add("2025/05/21", 40, color="red") assert 183 < s1.left < 184 assert 227 < s1.top < 229 - - -@pytest.mark.parametrize("date", ["2025/05/21", "2025-5-21", "2025.5.21"]) -def test_strptime(date: str): - from pptxlib.contrib.gantt import strptime - - d = strptime(date) - assert d.year == 2025 - assert d.month == 5 - assert d.day == 21 - - -def test_strptime_invalid_separator(): - from pptxlib.contrib.gantt import strptime - - with pytest.raises(ValueError): - strptime("2025!05!21") - - -def test_strptime_invalid_count(): - from pptxlib.contrib.gantt import strptime - - with pytest.raises(ValueError): - strptime("2025/05/21/x") diff --git a/tests/contrib/test_gantt_unit.py b/tests/contrib/test_gantt_unit.py index 42f9c2d..53c685d 100644 --- a/tests/contrib/test_gantt_unit.py +++ b/tests/contrib/test_gantt_unit.py @@ -89,3 +89,27 @@ def test_name_day(): gantt = GanttFrame(datetime(2025, 4, 1), datetime(2025, 9, 10), kind="day") assert gantt.name == "2025/04/01-2025/09/10-day" + + +@pytest.mark.parametrize("date", ["2025/05/21", "2025-5-21", "2025.5.21"]) +def test_strptime(date: str): + from pptxlib.contrib.gantt import strptime + + d = strptime(date) + assert d.year == 2025 + assert d.month == 5 + assert d.day == 21 + + +def test_strptime_invalid_separator(): + from pptxlib.contrib.gantt import strptime + + with pytest.raises(ValueError): + strptime("2025!05!21") + + +def test_strptime_invalid_count(): + from pptxlib.contrib.gantt import strptime + + with pytest.raises(ValueError): + strptime("2025/05/21/x") From a9f524dd04c73d778e29a2dea3e6641b5648b368 Mon Sep 17 00:00:00 2001 From: Daizu Date: Mon, 11 Aug 2025 07:15:02 +0900 Subject: [PATCH 3/3] gantt.py: Update strptime to handle date strings with additional time components --- lcov.info | 15 ++++++++------- src/pptxlib/contrib/gantt.py | 2 ++ tests/contrib/test_gantt_unit.py | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lcov.info b/lcov.info index 9350f81..48fc2f2 100644 --- a/lcov.info +++ b/lcov.info @@ -341,16 +341,17 @@ DA:205,1 DA:207,1 DA:210,1 DA:211,1 -DA:212,1 DA:213,1 +DA:214,1 DA:215,1 -DA:216,1 +DA:217,1 DA:218,1 -DA:219,1 +DA:220,1 DA:221,1 -DA:222,1 -LF:139 -LH:139 +DA:223,1 +DA:224,1 +LF:140 +LH:140 FN:16,35,date_index FNDA:1,date_index FN:38,42,fiscal_year @@ -375,7 +376,7 @@ FN:175,176,GanttChart.y FNDA:1,GanttChart.y FN:178,207,GanttChart.add FNDA:1,GanttChart.add -FN:210,222,strptime +FN:210,224,strptime FNDA:1,strptime FNF:13 FNH:13 diff --git a/src/pptxlib/contrib/gantt.py b/src/pptxlib/contrib/gantt.py index b6c3854..0ef9890 100644 --- a/src/pptxlib/contrib/gantt.py +++ b/src/pptxlib/contrib/gantt.py @@ -208,6 +208,8 @@ def add( def strptime(date: str) -> datetime: + date = date.split(maxsplit=1)[0] + for sep in ["/", "-", "."]: if sep in date: break diff --git a/tests/contrib/test_gantt_unit.py b/tests/contrib/test_gantt_unit.py index 53c685d..da711c0 100644 --- a/tests/contrib/test_gantt_unit.py +++ b/tests/contrib/test_gantt_unit.py @@ -91,7 +91,7 @@ def test_name_day(): assert gantt.name == "2025/04/01-2025/09/10-day" -@pytest.mark.parametrize("date", ["2025/05/21", "2025-5-21", "2025.5.21"]) +@pytest.mark.parametrize("date", ["2025/05/21", "2025-5-21", "2025.5.21 1:1:1"]) def test_strptime(date: str): from pptxlib.contrib.gantt import strptime