from __future__ import annotations

import pytest
from django import forms
from django.core import exceptions
from django.test import SimpleTestCase

from django_mysql.forms import SimpleListField, SimpleSetField


class TestSimpleListField(SimpleTestCase):
    def test_valid(self):
        field = SimpleListField(forms.CharField())
        value = field.clean("a,b,c")
        assert value == ["a", "b", "c"]

    def test_to_python_no_leading_commas(self):
        field = SimpleListField(forms.IntegerField())
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean(",1")
        assert excinfo.value.messages[0] == "No leading, trailing, or double commas."

    def test_to_python_no_trailing_commas(self):
        field = SimpleListField(forms.IntegerField())
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("1,")
        assert excinfo.value.messages[0] == "No leading, trailing, or double commas."

    def test_to_python_no_double_commas(self):
        field = SimpleListField(forms.IntegerField())
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("1,,2")
        assert excinfo.value.messages[0] == "No leading, trailing, or double commas."

    def test_to_python_base_field_does_not_validate(self):
        field = SimpleListField(forms.IntegerField())
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("a,b,9")
        assert (
            excinfo.value.messages[0]
            == "Item 1 in the list did not validate: Enter a whole number."
        )

    def test_validate_fail(self):
        field = SimpleListField(
            forms.ChoiceField(choices=(("a", "The letter A"), ("b", "The letter B")))
        )
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("a,c")
        assert excinfo.value.messages[0] == (
            "Item 2 in the list did not validate: Select a valid choice. "
            + "c is not one of the available choices."
        )

    def test_validators_fail(self):
        field = SimpleListField(forms.RegexField("[a-e]{2}"))
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("a,bc,de")
        assert (
            excinfo.value.messages[0]
            == "Item 1 in the list did not validate: Enter a valid value."
        )

    def test_validators_fail_base_max_length(self):
        field = SimpleListField(forms.CharField(max_length=5))
        with pytest.raises(exceptions.ValidationError) as excinfo:
            field.clean("longer,yes")
        assert excinfo.value.messages[0] == (
            "Item 1 in the list did not validate: Ensure this value has "
            + "at most 5 characters (it has 6)."
        )

    def test_validators_fail_base_min_max_length(self):