Add --weekly flag to csv command
- Add `write_csv_weekly()` to output.py: writes entries from multiple days as a single CSV with one header row, correct date per row - Add `-w`/`--weekly` flag to csv subparser - _cmd_csv branches on args.weekly: fetches week sections, formats per-day date strings, calls write_csv_weekly; --raw is honoured - Add TestWriteCsvWeekly with 6 tests - Update README with weekly csv usage examples
This commit is contained in:
parent
985ee28113
commit
cd8ca789aa
4 changed files with 134 additions and 10 deletions
|
|
@ -3,7 +3,13 @@ import io
|
|||
|
||||
import pytest
|
||||
|
||||
from timesheets.output import print_stories, print_summary, to_csv_entries, write_csv
|
||||
from timesheets.output import (
|
||||
print_stories,
|
||||
print_summary,
|
||||
to_csv_entries,
|
||||
write_csv,
|
||||
write_csv_weekly,
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Shared fixtures
|
||||
|
|
@ -129,6 +135,69 @@ class TestWriteCsv:
|
|||
assert rows[1][3] == "ticket 1"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# write_csv_weekly
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
DAY_SECTIONS = [
|
||||
(
|
||||
"22/03/26",
|
||||
[
|
||||
{"project": "bugs", "description": "ticket 1", "quantity": 1.0},
|
||||
{"project": "scrum", "description": "dsu", "quantity": 0.25},
|
||||
],
|
||||
),
|
||||
(
|
||||
"23/03/26",
|
||||
[
|
||||
{"project": "bugs", "description": "ticket 2", "quantity": 0.5},
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
class TestWriteCsvWeekly:
|
||||
def _run(self, day_sections=None, project_map=None):
|
||||
buf = io.StringIO()
|
||||
write_csv_weekly(
|
||||
DAY_SECTIONS if day_sections is None else day_sections,
|
||||
buf,
|
||||
project_map or {},
|
||||
)
|
||||
buf.seek(0)
|
||||
return list(csv.reader(buf))
|
||||
|
||||
def test_header_written_once(self):
|
||||
rows = self._run()
|
||||
assert rows[0] == ["Date*", "Project*", "Task", "Description", "Quantity"]
|
||||
assert sum(1 for r in rows if r[0] == "Date*") == 1
|
||||
|
||||
def test_row_count(self):
|
||||
rows = self._run()
|
||||
assert len(rows) == 1 + 3 # header + 3 entries across 2 days
|
||||
|
||||
def test_correct_date_per_row(self):
|
||||
rows = self._run()
|
||||
assert rows[1][0] == "22/03/26"
|
||||
assert rows[2][0] == "22/03/26"
|
||||
assert rows[3][0] == "23/03/26"
|
||||
|
||||
def test_empty_sections_produce_header_only(self):
|
||||
rows = self._run(day_sections=[])
|
||||
assert rows == [["Date*", "Project*", "Task", "Description", "Quantity"]]
|
||||
|
||||
def test_project_map_applied(self):
|
||||
rows = self._run(project_map=PROJECT_MAP)
|
||||
assert rows[1][1] == "[Factry] Historian"
|
||||
assert rows[1][2] == "[Historian] Bugs"
|
||||
|
||||
def test_quantity_format(self):
|
||||
rows = self._run()
|
||||
assert rows[1][4] == "1.00"
|
||||
assert rows[3][4] == "0.50"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# print_summary
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue