# Licensed under a 3-clause BSD style license - see LICENSE.rst
import pytest

# LOCAL
from astropy.io.votable import converters, exceptions, tree


def test_reraise():
    def fail():
        raise RuntimeError("This failed")

    try:
        try:
            fail()
        except RuntimeError as e:
            exceptions.vo_reraise(e, additional="From here")
    except RuntimeError as e:
        assert "From here" in str(e)
    else:
        assert False


def test_parse_vowarning():
    config = {"verify": "exception", "filename": "foo.xml"}
    pos = (42, 64)
    with pytest.warns(exceptions.W47) as w:
        field = tree.Field(None, name="c", datatype="char", config=config, pos=pos)
        converters.get_converter(field, config=config, pos=pos)

    parts = exceptions.parse_vowarning(str(w[0].message))

    match = {
        "number": 47,
        "is_exception": False,
        "nchar": 64,
        "warning": "W47",
        "is_something": True,
        "message": "Missing arraysize indicates length 1",
        "doc_url": "io/votable/api_exceptions.html#w47",
        "nline": 42,
        "is_warning": True,
    }
    assert parts == match


def test_suppress_warnings():
    cfg = {}
    warn = exceptions.W01("foo")

    with exceptions.conf.set_temp("max_warnings", 2):
        with pytest.warns(exceptions.W01) as record:
            exceptions._suppressed_warning(warn, cfg)
            assert len(record) == 1
            assert "suppressing" not in str(record[0].message)

        with pytest.warns(exceptions.W01, match="suppressing"):
            exceptions._suppressed_warning(warn, cfg)

        exceptions._suppressed_warning(warn, cfg)

    assert cfg["_warning_counts"][exceptions.W01] == 3
    assert exceptions.conf.max_warnings == 10
