Track 1.1 of master plan: expand from sexp-only tests to cover DTOs, HTTP signatures, HMAC auth, URL utilities, Jinja filters, calendar helpers, config freeze, activity bus registry, parse utilities, sexp helpers, error classes, and jinja bridge render API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
"""Tests for parse utility functions."""
|
|
from __future__ import annotations
|
|
|
|
from datetime import time, datetime, timezone
|
|
|
|
from shared.browser.app.utils.parse import parse_time, parse_cost, parse_dt
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# parse_time
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestParseTime:
|
|
def test_valid_time(self):
|
|
result = parse_time("14:30")
|
|
assert result == time(14, 30)
|
|
|
|
def test_midnight(self):
|
|
result = parse_time("00:00")
|
|
assert result == time(0, 0)
|
|
|
|
def test_end_of_day(self):
|
|
result = parse_time("23:59")
|
|
assert result == time(23, 59)
|
|
|
|
def test_none_input(self):
|
|
assert parse_time(None) is None
|
|
|
|
def test_empty_string(self):
|
|
assert parse_time("") is None
|
|
|
|
def test_invalid_format(self):
|
|
assert parse_time("not-a-time") is None
|
|
|
|
def test_invalid_hours(self):
|
|
assert parse_time("25:00") is None
|
|
|
|
def test_single_digit(self):
|
|
result = parse_time("9:05")
|
|
assert result == time(9, 5)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# parse_cost
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestParseCost:
|
|
def test_valid_float(self):
|
|
assert parse_cost("19.99") == 19.99
|
|
|
|
def test_integer_string(self):
|
|
assert parse_cost("10") == 10.0
|
|
|
|
def test_zero(self):
|
|
assert parse_cost("0") == 0.0
|
|
|
|
def test_none_input(self):
|
|
assert parse_cost(None) is None
|
|
|
|
def test_empty_string(self):
|
|
assert parse_cost("") is None
|
|
|
|
def test_invalid_string(self):
|
|
assert parse_cost("not-a-number") is None
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# parse_dt
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestParseDt:
|
|
def test_iso_format(self):
|
|
result = parse_dt("2025-06-15T14:30:00")
|
|
assert isinstance(result, datetime)
|
|
assert result.year == 2025
|
|
assert result.month == 6
|
|
assert result.day == 15
|
|
|
|
def test_naive_gets_utc(self):
|
|
result = parse_dt("2025-06-15T14:30:00")
|
|
assert result.tzinfo == timezone.utc
|
|
|
|
def test_aware_preserved(self):
|
|
result = parse_dt("2025-06-15T14:30:00+01:00")
|
|
assert result.tzinfo is not None
|
|
|
|
def test_none_input(self):
|
|
assert parse_dt(None) is None
|
|
|
|
def test_empty_string(self):
|
|
assert parse_dt("") is None
|
|
|
|
def test_date_only(self):
|
|
result = parse_dt("2025-06-15")
|
|
assert result.year == 2025
|