"""Tests for the autocast module."""

import pytest
from pytest import param

from bumpversion import autocast


@pytest.mark.parametrize(
    "value, expected",
    [
        param("true", True, id="true"),
        param("false", False, id="false"),
        param("True", True, id="True"),
        param("False", False, id="False"),
    ],
)
def test_boolify_valid(value: str, expected: bool) -> None:
    """Test the boolify function."""
    assert autocast.boolify(value) == expected


@pytest.mark.parametrize(
    "value",
    [
        param(1, id="int"),
        param("string", id="str"),
    ],
)
def test_boolify_invalid(value):
    """Test the boolify function."""
    with pytest.raises(ValueError):
        autocast.boolify(value)


def test_noneify():
    """noneify should return None if the string is None."""
    assert autocast.noneify("None") is None
    with pytest.raises(ValueError):
        autocast.noneify("0")


@pytest.mark.parametrize(
    "value,expected",
    [
        param("1,2,3,4", [1, 2, 3, 4], id="int"),
        param("1\n2\n3\n4", [1, 2, 3, 4], id="int"),
        param("s,t,r", ["s", "t", "r"], id="str"),
        param("s,\nt,\nr\n", ["s,", "t,", "r"], id="str_newline"),
        param("1.1,2,3.14", [1.1, 2.0, 3.14], id="float"),
        param("True,False,true,false", [True, False, True, False], id="bool"),
        param("None,None,None", [None, None, None], id="none"),
        param("\nNone\nNone\nNone\n", [None, None, None], id="none with extra newlines"),
    ],
)
def test_listify_valid(value, expected):
    """Test the listify function."""
    assert autocast.listify(value) == expected


def test_listify_invalid():
    """Every element of the list should be the same type."""
    with pytest.raises(TypeError):
        autocast.listify("True,1,None")

    with pytest.raises(ValueError):
        autocast.listify("I am not a list")


@pytest.mark.parametrize(
    "value,expected",
    [
        param("true", True, id="true"),
        param("false", False, id="false"),
        param("True", True, id="True"),
        param("False", False, id="False"),
        param("1,2,3,4", [1, 2, 3, 4], id="int-list"),
        param("s,t,r", ["s", "t", "r"], id="str-list"),
        param("s,\nt,\nr\n", ["s,", "t,", "r"], id="str-list-newline"),
        param("1", 1, id="int"),
        param("1.0", 1.0, id="float"),
        param(1, 1, id="real-int"),
    ],
)
def test_autocast_value(value, expected):
    """Test basic functionality of autocast_value."""
    assert autocast.autocast_value(value) == expected
