def cumulative():
    scorer = CumulativeScoreKeeper()

    with let(__scorer, scorer):
        yield

    value(__scorer).suite_finished(scorer.score)
def weight(maximum):
    scorer = CumulativeScoreKeeper()

    with let(__scorer, scorer):
        yield

    score = scorer.score

    value(__scorer).suite_finished(score.rescale(maximum))
def function_reftest(identifier):
    if not identifier in dir(value(reference_module)):
        raise Exception(f'Bug in tests: reference module does not contain member called "{identifier}"')
    
    with when(defined(identifier, value(tested_module))), let(tested_function_name, identifier):
        reference_function = getattr(value(reference_module), identifier)
        tested_function = getattr(value(tested_module), identifier)

        with check_function_against_reference_implementation(tested=tested_function, reference=reference_function) as check:
            yield check
def all_or_nothing():
    scorer = CumulativeScoreKeeper()

    with let(__scorer, scorer):
        yield

    score = scorer.score

    if not score.is_perfect:
        score = score.zero

    value(__scorer).suite_finished(score)
def when(condition):
    '''
    Adds an extra condition
    '''
    old_condition = value(__condition)

    with let(__condition, lambda: old_condition() and condition()):
        yield
def __load_module(filename, module_name, directory):
    # If no directory is specified, fetch the test file's directory
    if not directory:
        directory = value(test_directory)

    full_path = os.path.join(directory, filename)

    return load_code(full_path, module_name)
 def failure_message_generator(*, failure, **kwargs):
     failure_message = value(__failure_message)
     
     if failure_message:
         return format.vbox(f'Verifying {call_string}', \
                            format.indent(2, failure_message), \
                            format.indent(2, str(failure)))
     else:
         raise Exception('Bug in reference tests: no failure message set')
def __add_callback(event, callback):
    '''
    Helper function. Adds a callback to and event,
    the event being __passed, __failed or __skipped.
    '''
    old_callback = value(event)
    chained = __chain(old_callback, callback)

    with let(event, chained):
        yield
    def failure_callback(*, failure):
        nonlocal failure_index

        if failure_index != 1:
            print('-' * 40)

        generator = value(__failure_message_generator)
        message = generator(failure=failure)
        message_lines = format.hbox(f'[{failure_index}] ', message).format()
        print("\n".join(message_lines))

        failure_index += 1
    def check(*args, **kwargs):
        positional_parameter_names = __get_positional_parameter_names(reference)
        function_name = value(tested_function_name)
        positional_argument_strings = [ f'{name} = {str(arg)}' for name, arg in zip(positional_parameter_names, args) ]
        keyword_argument_strings = [ f'{k}={v}' for k, vi in kwargs.items() ]
        arguments_string = ', '.join(positional_argument_strings + keyword_argument_strings)
        call_string = f'{function_name}({arguments_string})'

        def failure_message_generator(*, failure, **kwargs):
            failure_message = value(__failure_message)
            
            if failure_message:
                return format.vbox(f'Verifying {call_string}', \
                                   format.indent(2, failure_message), \
                                   format.indent(2, str(failure)))
            else:
                raise Exception('Bug in reference tests: no failure message set')

            
        def test_function():
            def check_return_values(expected, actual):
                __failure_message.value = f'Comparing return values'
                assert expected == actual, f'Expected {expected}, got {actual}'

            def check_positional_argument(index, name, expected, actual):
                __failure_message.value = f'Comparing {name} (positional argument #{index + 1})'
                assert expected == actual, f'Expected {expected}, got {actual}'
                
            def check_positional_arguments(names, expecteds, actuals):
                for (index, name, expected, actual) in zip(range(len(names)), names, expecteds, actuals):
                    check_positional_argument(index, name, expected, actual)
                
            actual_args = deepcopy(args)
            actual_kwargs = deepcopy(kwargs)
            expected_args = deepcopy(args)
            expected_kwargs = deepcopy(kwargs)

            __failure_message.value = f'Exception occurred during function call'
            actual_result = tested(*actual_args, **actual_kwargs)
            expected_result = reference(*expected_args, **expected_kwargs)

            check_return_values(expected=expected_result, actual=actual_result)
            check_positional_arguments(positional_parameter_names, expected_args, actual_args)
                

        with reporting.default_failure_message_generator(failure_message_generator), \
             let(__failure_message, None):
            test(test_function)
def current_test_function():
    # Inside a @test annotated function, returns the function
    return value(__test_function)
 def signal_passed():
     value(__passed)()
def __should_test_run():
    return value(__condition)()
 def skipped():
     value(__scorer).test_skipped()
 def passed():
     value(__scorer).test_passed()
def default_failure_message_generator(message_generator):
    if value(__failure_message_generator) != __dummy_failure_message_generator:
        yield
    else:
        with failure_message_generator(message_generator):
            yield
 def signal_skipped():
     value(__skipped)()
 def failed(*args, **kwargs):
     value(__scorer).test_failed()
 def signal_failed(exception):
     value(__failed)(failure=exception)