예제 #1
0
def test_with(index,
              context_vals=False, # whether to check number of context vals
              context_tests=None, # check on context expressions
              body=None,
              undefined_msg=None,
              context_vals_len_msg=None,
              context_vals_msg=None,
              expand_message=True,
              state=None):
    """Test a with statement.
with open_file('...') as bla:

    [ open_file('...').__enter__() ]


with open_file('...') as file:
    [ ]

    """
    rep = Reporter.active_reporter
    rep.set_tag("fun", "test_with")

    check_with = partial(check_node, 'withs', index-1, "`with` statement", MSG_MISSING, state=state)

    child =  check_with(MSG_PREPEND  if expand_message else "")
    child2 = check_with(MSG_PREPEND2 if expand_message else "")
    quiet_child = quiet(1, child)

    if context_vals:
        # test num context vars ----
        too_many = len(child.student_parts['context']) > len(child.solution_parts['context'])
        if too_many:
            _msg = child.build_message(MSG_NUM_CTXT)
            rep.do_test(Test(Feedback(_msg, child.student_tree)))

        # test context var names ----
        for i in range(len(child.solution_parts['context'])):
            ctxt_state = check_part_index('context', i, "", state=child)
            has_equal_part('target_vars', MSG_CTXT_NAMES, state=ctxt_state)

    
    # Context sub tests ----
    if context_tests and not isinstance(context_tests, list): context_tests = [context_tests]

    for i, context_test in enumerate(context_tests or []):
        # partial the substate check, because the function uses two prepended messages
        check_context = partial(check_part_index, 'context', i, "%s context"%utils.get_ord(i+1), MSG_NUM_CTXT2)

        check_context(state=child)                   # test exist

        ctxt_state = check_context(state=child2)     # sub tests
        multi(context_test, state=ctxt_state)
    
    # Body sub tests ----
    if body is not None:
        body_state = check_part('body', 'body', state=child2)

        with_context(body, state=body_state)
예제 #2
0
def test_try_except(index=1,
                    not_called_msg=None,
                    body=None,
                    handlers={},
                    except_missing_msg = None,
                    orelse=None,
                    orelse_missing_msg=None,
                    finalbody=None,
                    finalbody_missing_msg=None,
                    expand_message=True,
                    state=None):
    """Test whether the student correctly coded a `try-except` block.  

    This function allows you to test specific parts of a try-except block.
    A try-except block consists of 4 parts: a body, error handlers, plus (rarely) an
    else and final block. ::

        try:              print(hello)
        except NameError: print('hello what?')
        except:           print('unexplained error')
        else:             print('else block')
        finally:          print('final block')
    
    Args:
        index (int): index of the try-except block to check. 
        not_called_msg: override the default message when too few try-except blocks found in student code.
        body: sub-sct to test the code of the `try` block. 
        handlers: a dictionary, where the keys are the error classes you expect the student to capture (for the general `except:`, use `'all'`), and the values are sub-SCTs for each of these `except` blocks.
        except_missing_message: override the default message when a expect block in the handlers arg is missing.
        orelse: similar to body, but for the else block.
        finalbody: similar to body, but for the finally block. 
        _missing_msg: custom messages if the orelse, or finalbody pieces are missing.
"""

    rep = Reporter.active_reporter
    rep.set_tag("fun", "test_try_except")

    # TODO: alternatively, could have missing_msg not use prepended messages
    #       then we wouldn't have to run check_part twice for everything
    child = check_node('try_excepts', index-1, "try-except block", MSG_MISSING, MSG_PREPEND, state)
    quiet_child = quiet(1, state=child)

    multi(body, state=check_part("body", "body", child))       # subtests

    # handler tests
    for key,value in handlers.items():
        incorrect_part = "{} `except` block".format('general' if key == 'all' else "`%s`"%key)

        # run to see if index exists, since the message depends on using the quiet child :o
        check_handler = partial(check_part_index, 'handlers', key, incorrect_part, MSG_MISSING_PART)

        check_handler(state=quiet_child)                       # exists
        multi(value, state=check_handler(state=child))         # subtests

    # test orelse and finalbody
    check = partial(check_part, missing_msg = MSG_MISSING_PART)

    # test orelse 
    if child.solution_parts['orelse']:
        check('orelse', "`else` part", quiet_child)                         # exists
        multi(orelse, state=check('orelse', "`else` part", child))          # subtests

    # test orelse 
    if child.solution_parts['finalbody']:
        check('finalbody', "`finally` part", quiet_child)                   # exists
        multi(finalbody, state=check('finalbody', "`finally` part", child)) # subtests
예제 #3
0
def test_with(
        index,
        context_vals=False,  # whether to check number of context vals
        context_tests=None,  # check on context expressions
        body=None,
        undefined_msg=None,
        context_vals_len_msg=None,
        context_vals_msg=None,
        expand_message=True,
        state=None):
    """Test a with statement.
with open_file('...') as bla:

    [ open_file('...').__enter__() ]


with open_file('...') as file:
    [ ]

    """
    rep = Reporter.active_reporter
    rep.set_tag("fun", "test_with")

    check_with = partial(check_node,
                         'withs',
                         index - 1,
                         "`with` statement",
                         MSG_MISSING,
                         state=state)

    child = check_with(MSG_PREPEND if expand_message else "")
    child2 = check_with(MSG_PREPEND2 if expand_message else "")
    quiet_child = quiet(1, child)

    if context_vals:
        # test num context vars ----
        too_many = len(child.student_parts['context']) > len(
            child.solution_parts['context'])
        if too_many:
            _msg = child.build_message(MSG_NUM_CTXT)
            rep.do_test(Test(Feedback(_msg, child.student_tree)))

        # test context var names ----
        for i in range(len(child.solution_parts['context'])):
            ctxt_state = check_part_index('context', i, "", state=child)
            has_equal_part('target_vars', MSG_CTXT_NAMES, state=ctxt_state)

    # Context sub tests ----
    if context_tests and not isinstance(context_tests, list):
        context_tests = [context_tests]

    for i, context_test in enumerate(context_tests or []):
        # partial the substate check, because the function uses two prepended messages
        check_context = partial(check_part_index, 'context', i,
                                "%s context" % utils.get_ord(i + 1),
                                MSG_NUM_CTXT2)

        check_context(state=child)  # test exist

        ctxt_state = check_context(state=child2)  # sub tests
        multi(context_test, state=ctxt_state)

    # Body sub tests ----
    if body is not None:
        body_state = check_part('body', 'body', state=child2)

        with_context(body, state=body_state)
예제 #4
0
def test_try_except(index=1,
                    not_called_msg=None,
                    body=None,
                    handlers={},
                    except_missing_msg = None,
                    orelse=None,
                    orelse_missing_msg=None,
                    finalbody=None,
                    finalbody_missing_msg=None,
                    expand_message=True,
                    state=None):
    """Test whether the student correctly coded a `try-except` block.  

    This function allows you to test specific parts of a try-except block.
    A try-except block consists of 4 parts: a body, error handlers, plus (rarely) an
    else and final block. ::

        try:              print(hello)
        except NameError: print('hello what?')
        except:           print('unexplained error')
        else:             print('else block')
        finally:          print('final block')
    
    Args:
        index (int): index of the try-except block to check. 
        not_called_msg: override the default message when too few try-except blocks found in student code.
        body: sub-sct to test the code of the `try` block. 
        handlers: a dictionary, where the keys are the error classes you expect the student to capture (for the general `except:`, use `'all'`), and the values are sub-SCTs for each of these `except` blocks.
        except_missing_message: override the default message when a expect block in the handlers arg is missing.
        orelse: similar to body, but for the else block.
        finalbody: similar to body, but for the finally block. 
        _missing_msg: custom messages if the orelse, or finalbody pieces are missing.
"""

    rep = Reporter.active_reporter

    # TODO: alternatively, could have missing_msg not use prepended messages
    #       then we wouldn't have to run check_part twice for everything
    child = check_node('try_excepts', index-1, "try-except block", MSG_MISSING, MSG_PREPEND, state)
    quiet_child = quiet(1, state=child)

    multi(body, state=check_part("body", "body", child))       # subtests

    # handler tests
    for key,value in handlers.items():
        incorrect_part = "{} `except` block".format('general' if key == 'all' else "`%s`"%key)

        # run to see if index exists, since the message depends on using the quiet child :o
        check_handler = partial(check_part_index, 'handlers', key, incorrect_part, MSG_MISSING_PART)

        check_handler(state=quiet_child)                       # exists
        multi(value, state=check_handler(state=child))         # subtests

    # test orelse and finalbody
    check = partial(check_part, missing_msg = MSG_MISSING_PART)

    # test orelse 
    if child.solution_parts['orelse']:
        check('orelse', "`else` part", quiet_child)                         # exists
        multi(orelse, state=check('orelse', "`else` part", child))          # subtests

    # test orelse 
    if child.solution_parts['finalbody']:
        check('finalbody', "`finally` part", quiet_child)                   # exists
        multi(finalbody, state=check('finalbody', "`finally` part", child)) # subtests
예제 #5
0
def test_with(
        index,
        context_vals=False,  # whether to check number of context vals
        context_tests=None,  # check on context expressions
        body=None,
        undefined_msg=None,
        context_vals_len_msg=None,
        context_vals_msg=None,
        expand_message=True,
        state=None):
    """Test a with statement.
with open_file('...') as bla:

    [ open_file('...').__enter__() ]


with open_file('...') as file:
    [ ]

    """
    rep = Reporter.active_reporter

    check_with = partial(check_node,
                         'withs',
                         index - 1,
                         "`with` statement",
                         MSG_MISSING,
                         state=state)

    child = check_with(MSG_PREPEND if expand_message else "")
    child2 = check_with(MSG_PREPEND2 if expand_message else "")
    quiet_child = quiet(1, child)

    if context_vals:
        # test context var names ----
        has_context(incorrect_msg=context_vals_msg or MSG_CTXT_NAMES,
                    exact_names=True,
                    state=child)

        # test num context vars ----
        has_equal_part_len('context', MSG_NUM_CTXT, state=child)

    # Context sub tests ----
    if context_tests and not isinstance(context_tests, list):
        context_tests = [context_tests]

    for i, context_test in enumerate(context_tests or []):
        # partial the substate check, because the function uses two prepended messages
        check_context = partial(check_part_index, 'context', i,
                                "%s context" % utils.get_ord(i + 1),
                                MSG_NUM_CTXT2)

        check_context(state=child)  # test exist

        ctxt_state = check_context(state=child2)  # sub tests
        multi(context_test, state=ctxt_state)

    # Body sub tests ----
    if body is not None:
        body_state = check_part('body', 'body', state=child2)

        with_context(body, state=body_state)