"""
Testing that your program respond as expected in negative situations is very important.
These tests exemplify how to check that some code raises the right Exception.
"""
# TODO BreakingPoint exception

import pytest


def raise_exception():
    raise KeyError("This function raises an exception")
    # Note that you should use a message CONSTANT instead of a direct string


def test_raise_exception():
    with pytest.raises(KeyError):
        raise KeyError("Is expected")

    with pytest.raises(KeyError):
        raise_exception()

    with pytest.raises(KeyError) as raised_exception:
        raise_exception()
        assert raised_exception.msg == "This function raises an exception."


@pytest.mark.xfail() # we expect this test to fail, just to prove the mechanism
def test_raise_unexpected_exception():
    raise AttributeError
    # It will add an xfail counter in the Result line
    # something like: ========== 1 passed, 2 xfailed in 0.08 seconds =================


@pytest.mark.xfail(raises=KeyError)
def test_expected_other_exception():
    """
    Some times something fails, you make a test but you cannot find a solution after many hours.
    Instead of deleting the test for the suite to pass and forgetting about it; preserve the test,
    mark it as xFail and tackle it in the future.
    """
    with pytest.raises(AttributeError):
        raise_exception()