# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/oops.py
# class FunctionProgrammingError(ProgrammingError):
#     r"""
#     A more specific type of :class:`ProgrammingError` that occurs when a
#     user's :func:`@Operation <esc.commands.Operation>` decorator or function
#     parameters are invalid or function tests fail.
# 
#     The distinction is mostly for convenience within esc's codebase rather
#     than because client code needs to tell the difference from other
#     :class:`ProgrammingError`\ s; this class wraps some handy logic for
#     generating a standardized message.
#     """
#     def __init__(self, operation, problem):
#         super().__init__()
#         self.operation = operation
#         self.function_name = self.operation.function.__name__
#         self.key = self.operation.key
#         self.description = self.operation.description
#         self.problem = problem
# 
#         self.message = (f"The function '{self.function_name}' "
#                         f"(key '{self.key}', description '{self.description}') "
#                         f"{self.problem}. ")
# 
#     def __str__(self):
#         return self.message


from decimal import Decimal
from esc.commands import Menu, Operation, main_menu
from esc.oops import FunctionProgrammingError
import pytest


def test_ensure_success_fail():
    "We can run a test that fails because the result doesn't match the after assertion."

    tc, op = division_test_case(before=[4, 2], after=[7])
    with pytest.raises(FunctionProgrammingError) as excinfo:
        tc.execute(op)
    assert "failed a self-test" in str(excinfo.value)
    assert "as the final stack" in str(excinfo.value)


def test_ensure_raises_ok():
    "We can run a test that checks for raises and succeeds."
    tc, op = division_test_case(before=[4, 0], raises=ZeroDivisionError)
    tc.execute(op)  # should not raise


def test_ensure_raises_fail():
    "We can run a test that checks for raises and doesn't find any exception."
    tc, op = division_test_case(before=[4, 2], raises=ZeroDivisionError)
    with pytest.raises(FunctionProgrammingError) as excinfo:
        tc.execute(op)
    assert "failed a self-test" in str(excinfo.value)
    assert "was not raised" in str(excinfo.value)


def test_ensure_raises_wrong_type_fail():
    "We can run a test that checks for raises and gets the wrong exc type, thus fails."
    tc, op = division_test_case(before=[4, 0], raises=IsADirectoryError)

# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/oops.py
# class FunctionProgrammingError(ProgrammingError):
#     r"""
#     A more specific type of :class:`ProgrammingError` that occurs when a
#     user's :func:`@Operation <esc.commands.Operation>` decorator or function
#     parameters are invalid or function tests fail.
# 
#     The distinction is mostly for convenience within esc's codebase rather
#     than because client code needs to tell the difference from other
#     :class:`ProgrammingError`\ s; this class wraps some handy logic for
#     generating a standardized message.
#     """
#     def __init__(self, operation, problem):
#         super().__init__()
#         self.operation = operation
#         self.function_name = self.operation.function.__name__
#         self.key = self.operation.key
#         self.description = self.operation.description
#         self.problem = problem
# 
#         self.message = (f"The function '{self.function_name}' "
#                         f"(key '{self.key}', description '{self.description}') "
#                         f"{self.problem}. ")
# 
#     def __str__(self):
#         return self.message


# Path: tests/esc/test_functest.py
from decimal import Decimal
from esc.commands import Menu, Operation, main_menu
from esc.oops import FunctionProgrammingError
import pytest



def test_ensure_success_fail():
    "We can run a test that fails because the result doesn't match the after assertion."

    tc, op = division_test_case(before=[4, 2], after=[7])
    with pytest.raises(FunctionProgrammingError) as excinfo:
        tc.execute(op)
    assert "failed a self-test" in str(excinfo.value)
    assert "as the final stack" in str(excinfo.value)


def test_ensure_raises_ok():
    "We can run a test that checks for raises and succeeds."
    tc, op = division_test_case(before=[4, 0], raises=ZeroDivisionError)
    tc.execute(op)  # should not raise


def test_ensure_raises_fail():
    "We can run a test that checks for raises and doesn't find any exception."
    tc, op = division_test_case(before=[4, 2], raises=ZeroDivisionError)
    with pytest.raises(FunctionProgrammingError) as excinfo:
        tc.execute(op)
    assert "failed a self-test" in str(excinfo.value)
    assert "was not raised" in str(excinfo.value)


def test_ensure_raises_wrong_type_fail():
    "We can run a test that checks for raises and gets the wrong exc type, thus fails."
    tc, op = division_test_case(before=[4, 0], raises=IsADirectoryError)

    with pytest.raises(FunctionProgrammingError) as excinfo: