Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions test/unit/test_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,9 @@ def test_invalid_entries(self):
entry_parser = EntryParser()
entry = entry_parser.parse(test_case[0])
self.assertIsNone(entry)

def test_invalid_date_raises_value_error(self):
"""Test that entries with invalid dates raise ValueError."""
entry_parser = EntryParser()
with self.assertRaises(ValueError):
entry_parser.parse("2025-27-27 17:00 misc: testing")
Comment thread
loganthomas marked this conversation as resolved.
Outdated
19 changes: 18 additions & 1 deletion test/unit/test_parse_date.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import datetime
import unittest

from utt.components.report_args import parse_date
from utt.components.entries import UttError
from utt.components.report_args import parse_absolute_date, parse_absolute_month, parse_date

VALID_ENTRIES = [
("monday", datetime.date(2015, 2, 11), datetime.date(2015, 2, 9), True),
Expand Down Expand Up @@ -29,3 +30,19 @@ def test_parse_date(self):
with self.subTest(report_date=report_date, today=today, is_past=is_past):
actual_report_date = parse_date(today, report_date, is_past)
self.assertEqual(actual_report_date, expected_report_date)

def test_invalid_date_raises_utt_error(self):
with self.assertRaises(UttError):
parse_absolute_date("invalid-date")

def test_invalid_month_raises_utt_error(self):
with self.assertRaises(UttError):
parse_absolute_month("invalid-month")

def test_valid_absolute_date(self):
result = parse_absolute_date("2024-01-15")
self.assertEqual(result, datetime.date(2024, 1, 15))

def test_valid_absolute_month(self):
result = parse_absolute_month("2024-01")
self.assertEqual(result, datetime.date(2024, 1, 1))
7 changes: 6 additions & 1 deletion utt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import utt.plugins
from utt.api import _v1
from utt.components.commands import Commands
from utt.components.entries import UttError


def iter_namespace(ns_pkg):
Expand Down Expand Up @@ -34,7 +35,11 @@ def main():
commands: Commands = _v1._private.container[Commands]
for command in commands:
if command.name == command_name:
_v1._private.container[command.handler_class]()
try:
_v1._private.container[command.handler_class]()
except UttError as e:
print("error: %s" % e, file=sys.stderr)
Comment thread
loganthomas marked this conversation as resolved.
Outdated
sys.exit(1)


if __name__ == "__main__":
Expand Down
14 changes: 12 additions & 2 deletions utt/components/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
Entries = List[Entry]


class UttError(Exception):
Comment thread
loganthomas marked this conversation as resolved.
Outdated
"""User-facing error with a friendly message."""

pass


def entries(entry_lines: EntryLines, entry_parser: EntryParser) -> Entries:
return list(_parse_log(entry_lines(), entry_parser))

Expand All @@ -26,12 +32,16 @@ def _parse_line(previous_entry: Optional[Entry], line_number: int, line: str, en
if not line:
return None

new_entry = entry_parser.parse(line)
try:
new_entry = entry_parser.parse(line)
except ValueError:
raise UttError("Invalid date at line %d: %s" % (line_number, line))
Comment thread
loganthomas marked this conversation as resolved.
Outdated

if new_entry is None:
raise SyntaxError("Invalid syntax at line %d: %s" % (line_number, line))
Comment thread
loganthomas marked this conversation as resolved.
Outdated

if previous_entry is not None and previous_entry.datetime > new_entry.datetime:
raise Exception("Error line %d. Not in chronological order: %s > %s" % (line_number, previous_entry, new_entry))
raise UttError("Line %d not in chronological order: %s" % (line_number, line))
Comment thread
loganthomas marked this conversation as resolved.
Outdated

previous_entry = new_entry
return previous_entry, new_entry
11 changes: 9 additions & 2 deletions utt/components/report_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from enum import Enum, auto
from typing import NamedTuple, Optional

from .entries import UttError
from .now import Now


Expand Down Expand Up @@ -76,7 +77,10 @@ def parse_date(today: datetime.date, datestring: str, is_past: bool):


def parse_absolute_date(datestring):
return datetime.datetime.strptime(datestring, "%Y-%m-%d").date()
try:
return datetime.datetime.strptime(datestring, "%Y-%m-%d").date()
except ValueError:
raise UttError("Invalid date: %s (expected YYYY-MM-DD)" % datestring)
Comment thread
loganthomas marked this conversation as resolved.
Outdated


def parse_relative_day(today, datestring):
Expand Down Expand Up @@ -168,7 +172,10 @@ def parse_integer_month(today, monthstring):


def parse_absolute_month(monthstring):
return datetime.datetime.strptime(monthstring, "%Y-%m").date()
try:
return datetime.datetime.strptime(monthstring, "%Y-%m").date()
except ValueError:
raise UttError("Invalid month: %s (expected YYYY-MM)" % monthstring)
Comment thread
loganthomas marked this conversation as resolved.
Outdated


def parse_month(today, monthstring):
Expand Down