import dataclasses

import pytest

from domain.postcode import Postcode


def test_postcode_uppercases() -> None:
    # act / assert
    assert Postcode("sw1a1aa").value == "SW1A1AA"


def test_postcode_strips_internal_spaces() -> None:
    # act / assert
    assert Postcode("sw1a 1aa").value == "SW1A1AA"


def test_postcode_strips_leading_and_trailing_whitespace() -> None:
    # act / assert
    assert Postcode("  sw1a 1aa  ").value == "SW1A1AA"


def test_postcode_strips_tabs_and_newlines() -> None:
    # CSV ingestion occasionally introduces stray whitespace characters; the
    # canonical form must absorb them just like literal spaces.
    # act / assert
    assert Postcode("sw1a\t1aa\n").value == "SW1A1AA"


def test_postcode_construction_is_idempotent() -> None:
    # arrange
    once = Postcode("sw1a 1aa")
    # act / assert
    assert Postcode(once.value).value == "SW1A1AA"


def test_postcode_empty_string() -> None:
    # act / assert
    assert Postcode("").value == ""


def test_postcode_str_returns_canonical_value() -> None:
    # act / assert
    assert str(Postcode("sw1a 1aa")) == "SW1A1AA"


def test_postcode_equality_ignores_surface_form() -> None:
    # Differing case / whitespace sanitise to the same canonical value, so
    # the value objects compare equal.
    # act / assert
    assert Postcode("sw1a 1aa") == Postcode("SW1A1AA")


def test_postcode_is_frozen() -> None:
    # arrange
    postcode = Postcode("SW1A1AA")
    # act / assert
    with pytest.raises(dataclasses.FrozenInstanceError):
        postcode.value = "OTHER"  # type: ignore[misc]
