コード例 #1
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
def call_in_test(call, already_assigned_names):
    if isinstance(call, GeneratorObject) or (isinstance(call, MethodCallContext) and isinstance(call.call, GeneratorObject)):
        callstring = call_as_string_for(call_name(call, already_assigned_names), call.args,
                                        call.definition, already_assigned_names)
        callstring = combine(callstring, str(len(call.calls)), template="list(islice(%s, %s))")
        callstring = addimport(callstring, ("itertools", "islice"))
    else:
        callstring = call_as_string_for(call_name(call, already_assigned_names), call.input,
                                        call.definition, already_assigned_names)
        callstring = addimport(callstring, import_for(call.definition))
    return callstring
コード例 #2
0
def call_in_test(call, already_assigned_names):
    if isinstance(call, GeneratorObject) or (isinstance(call, MethodCallContext) and isinstance(call.call, GeneratorObject)):
        callstring = call_as_string_for(call_name(call, already_assigned_names), call.args,
                                        call.definition, already_assigned_names)
        callstring = combine(callstring, str(len(call.calls)), template="list(islice(%s, %s))")
        callstring = addimport(callstring, ("itertools", "islice"))
    else:
        callstring = call_as_string_for(call_name(call, already_assigned_names), call.input,
                                        call.definition, already_assigned_names)
        callstring = addimport(callstring, import_for(call.definition))
    return callstring
コード例 #3
0
def call_as_string(object_name, args, assigned_names={}):
    """Generate code for calling an arbitrary object with given arguments.
    Use `call_as_string_for` when you have a definition to base the call on.

    >>> from test.helper import make_fresh_serialize
    >>> serialize = make_fresh_serialize()

    Since we don't have a definition to base the generated call on, we use
    keywords to name all arguments:
        >>> call_as_string('fun', {'a': serialize(1), 'b': serialize(2)})
        'fun(a=1, b=2)'
        >>> call_as_string('capitalize', {'str': serialize('string')})
        "capitalize(str='string')"

    Uses references to existing objects where possible...
        >>> result = call_as_string('call', {'f': serialize(call_as_string)})
        >>> result
        'call(f=call_as_string)'
        >>> result.uncomplete
        False

    ...but marks the resulting call as uncomplete if at least one of objects
    appearing in a call cannot be constructed.
        >>> result = call_as_string('map', {'f': serialize(lambda x: 42), 'L': serialize([1,2,3])})
        >>> result
        'map(L=[1, 2, 3], f=<TODO: function>)'
        >>> result.uncomplete
        True

    Uses names already assigned to objects instead of inlining their
    construction code.
        >>> mutable = serialize([])
        >>> call_as_string('merge', {'seq1': mutable, 'seq2': serialize([1,2,3])},
        ...     {mutable: 'alist'})
        'merge(seq1=alist, seq2=[1, 2, 3])'
    """
    arguments = []
    for arg, value in sorted(args.iteritems()):
        constructor = constructor_as_string(value, assigned_names)
        arguments.append(combine(arg, constructor, template="%s=%s"))
    return combine(object_name, join(", ", arguments), template="%s(%s)")
コード例 #4
0
ファイル: constructor.py プロジェクト: Br3nda/pythoscope
def call_as_string(object_name, args, assigned_names={}):
    """Generate code for calling an arbitrary object with given arguments.
    Use `call_as_string_for` when you have a definition to base the call on.

    >>> from test.helper import make_fresh_serialize
    >>> serialize = make_fresh_serialize()

    Since we don't have a definition to base the generated call on, we use
    keywords to name all arguments:
        >>> call_as_string('fun', {'a': serialize(1), 'b': serialize(2)})
        'fun(a=1, b=2)'
        >>> call_as_string('capitalize', {'str': serialize('string')})
        "capitalize(str='string')"

    Uses references to existing objects where possible...
        >>> result = call_as_string('call', {'f': serialize(call_as_string)})
        >>> result
        'call(f=call_as_string)'
        >>> result.uncomplete
        False

    ...but marks the resulting call as uncomplete if at least one of objects
    appearing in a call cannot be constructed.
        >>> result = call_as_string('map', {'f': serialize(lambda x: 42), 'L': serialize([1,2,3])})
        >>> result
        'map(L=[1, 2, 3], f=<TODO: function>)'
        >>> result.uncomplete
        True

    Uses names already assigned to objects instead of inlining their
    construction code.
        >>> mutable = serialize([])
        >>> call_as_string('merge', {'seq1': mutable, 'seq2': serialize([1,2,3])},
        ...     {mutable: 'alist'})
        'merge(seq1=alist, seq2=[1, 2, 3])'
    """
    arguments = []
    for arg, value in sorted(args.iteritems()):
        constructor = constructor_as_string(value, assigned_names)
        arguments.append(combine(arg, constructor, template="%s=%s"))
    return combine(object_name, join(", ", arguments), template="%s(%s)")
コード例 #5
0
def variable_assignment_line(left, right, already_assigned_names):
    if isinstance(right, ModuleVariableReference):
        constructor = code_string_from_module_variable_reference(right)
    elif isinstance(right, str):
        constructor = CodeString(right)
    elif isinstance(right, (Call, MethodCallContext)):
        constructor = call_in_test(right, already_assigned_names)
        # Associate the name with the call's output, not the call itself.
        already_assigned_names[right.output] = left
    else:
        constructor = constructor_as_string(right, already_assigned_names)
        already_assigned_names[right] = left
    return combine(left, constructor, "%s = %s")
コード例 #6
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
def variable_assignment_line(left, right, already_assigned_names):
    if isinstance(right, ModuleVariableReference):
        constructor = code_string_from_module_variable_reference(right)
    elif isinstance(right, str):
        constructor = CodeString(right)
    elif isinstance(right, (Call, MethodCallContext)):
        constructor = call_in_test(right, already_assigned_names)
        # Associate the name with the call's output, not the call itself.
        already_assigned_names[right.output] = left
    else:
        constructor = constructor_as_string(right, already_assigned_names)
        already_assigned_names[right] = left
    return combine(left, constructor, "%s = %s")
コード例 #7
0
def attribute_assignment_line(left, right, already_assigned_names):
    try:
        constructor = CodeString(already_assigned_names[right])
    except KeyError:
        constructor = constructor_as_string(right, already_assigned_names)
    return combine(left, constructor, "%s = %s")
コード例 #8
0
ファイル: constructor.py プロジェクト: Br3nda/pythoscope
def call_as_string_for(object_name, args, definition, assigned_names={}):
    """Generate code for calling an object with given arguments.

    >>> from test.helper import make_fresh_serialize
    >>> serialize = make_fresh_serialize()

    Puts varargs at the end of arguments list.
        >>> call_as_string_for('build_url',
        ...     {'proto': serialize('http'), 'params': serialize(('user', 'session', 'new'))},
        ...     Function('build_url', ['proto', '*params']))
        "build_url('http', 'user', 'session', 'new')"

    Works for lone varargs too.
        >>> call_as_string_for('concat', {'args': serialize(([1,2,3], [4,5], [6]))},
        ...     Function('concat', ['*args']))
        'concat([1, 2, 3], [4, 5], [6])'

    Uses assigned name for varargs as well.
        >>> args = serialize((1, 2, 3))
        >>> call_as_string_for('add', {'args': args}, Function('add', ['*args']), {args: 'atuple'})
        'add(*atuple)'

    Inlines extra keyword arguments in the call...
        >>> call_as_string_for('dict', {'kwargs': serialize({'one': 1, 'two': 2})},
        ...     Function('dict', ['**kwargs']))
        'dict(one=1, two=2)'

    ...even when they are combined with varargs.
        >>> call_as_string_for('wrap', {'a': serialize((1, 2, 3)), 'k': serialize({'x': 4, 'y': 5})},
        ...     Function('wrap', ['*a', '**k']))
        'wrap(1, 2, 3, x=4, y=5)'

    Uses assigned name for kwarg if present.
        >>> kwargs = serialize({'id': 42, 'model': 'user'})
        >>> call_as_string_for('filter_params', {'kwargs': kwargs},
        ...    Function('filter_params', ['**kwargs']), {kwargs: 'params'})
        'filter_params(**params)'

    Generates valid code when vararg has been named and kwarg wasn't.
        >>> args = serialize((1, 2, 3))
        >>> call_as_string_for('wrap', {'args': args, 'kwargs': serialize({'a': 6, 'b': 7})},
        ...     Function('wrap', ['*args', '**kwargs']), {args: 'atuple'})
        'wrap(a=6, b=7, *atuple)'

    When varargs are present all preceding arguments are positioned, not named.
        >>> call_as_string_for('sum', {'x': serialize(1), 'rest': serialize((2, 3))},
        ...     Function('sum', ['x', '*rest']))
        'sum(1, 2, 3)'

    When argument type requires import, the import is present in the imports list.
        >>> m = Module(None, 'myclasses')
        >>> cs = call_as_string_for('display',
        ...     {'obj': UserObject(None, Class('MyWindow', module=m))},
        ...     Function('display', ['obj']))
        >>> cs
        'display(MyWindow())'
        >>> cs.imports
        set([('myclasses', 'MyWindow')])
    """
    positional_args = []
    keyword_args = []
    vararg = None
    kwarg = None

    def getvalue(argname):
        return args[argname.lstrip("*")]

    skipped_an_arg = False
    for argname in arguments_of(definition):
        try:
            value = getvalue(argname)
            if argname.startswith("**"):
                if value in assigned_names.keys():
                    kwarg = CodeString("**%s" % assigned_names[value])
                else:
                    for karg, kvalue in map_as_kwargs(value):
                        valuecs = constructor_as_string(kvalue, assigned_names)
                        keyword_args.append(combine(karg, valuecs, "%s=%s"))
            elif argname.startswith("*"):
                if value in assigned_names.keys():
                    vararg = CodeString("*%s" % assigned_names[value])
                else:
                    code_strings = get_contained_objects_info(value, assigned_names)
                    positional_args.extend(code_strings)
            else:
                constructor = constructor_as_string(value, assigned_names)
                if skipped_an_arg:
                    keyword_args.append(combine(argname, constructor, "%s=%s"))
                else:
                    positional_args.append(constructor)
        except KeyError:
            skipped_an_arg = True

    arguments = join(', ', filter(None, (positional_args + keyword_args + [vararg] + [kwarg])))
    return combine(object_name, arguments, "%s(%s)")
コード例 #9
0
ファイル: constructor.py プロジェクト: Br3nda/pythoscope
def get_objects_mapping_info(mapping, assigned_names):
    for key, value in mapping:
        keycs = constructor_as_string(key, assigned_names)
        valuecs = constructor_as_string(value, assigned_names)
        yield combine(keycs, valuecs, "%s: %s")
コード例 #10
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
 def equal_assertion(self, expected, actual):
     return combine(expected, actual, "self.assertEqual(%s, %s)")
コード例 #11
0
 def raises_assertion(self, exception, call):
     return combine(exception, call, "self.assertRaises(%s, %s)")
コード例 #12
0
def call_as_string_for(object_name, args, definition, assigned_names={}):
    """Generate code for calling an object with given arguments.

    >>> from test.helper import make_fresh_serialize
    >>> serialize = make_fresh_serialize()

    Puts varargs at the end of arguments list.
        >>> call_as_string_for('build_url',
        ...     {'proto': serialize('http'), 'params': serialize(('user', 'session', 'new'))},
        ...     Function('build_url', ['proto', '*params']))
        "build_url('http', 'user', 'session', 'new')"

    Works for lone varargs too.
        >>> call_as_string_for('concat', {'args': serialize(([1,2,3], [4,5], [6]))},
        ...     Function('concat', ['*args']))
        'concat([1, 2, 3], [4, 5], [6])'

    Uses assigned name for varargs as well.
        >>> args = serialize((1, 2, 3))
        >>> call_as_string_for('add', {'args': args}, Function('add', ['*args']), {args: 'atuple'})
        'add(*atuple)'

    Inlines extra keyword arguments in the call...
        >>> call_as_string_for('dict', {'kwargs': serialize({'one': 1, 'two': 2})},
        ...     Function('dict', ['**kwargs']))
        'dict(one=1, two=2)'

    ...even when they are combined with varargs.
        >>> call_as_string_for('wrap', {'a': serialize((1, 2, 3)), 'k': serialize({'x': 4, 'y': 5})},
        ...     Function('wrap', ['*a', '**k']))
        'wrap(1, 2, 3, x=4, y=5)'

    Uses assigned name for kwarg if present.
        >>> kwargs = serialize({'id': 42, 'model': 'user'})
        >>> call_as_string_for('filter_params', {'kwargs': kwargs},
        ...    Function('filter_params', ['**kwargs']), {kwargs: 'params'})
        'filter_params(**params)'

    Generates valid code when vararg has been named and kwarg wasn't.
        >>> args = serialize((1, 2, 3))
        >>> call_as_string_for('wrap', {'args': args, 'kwargs': serialize({'a': 6, 'b': 7})},
        ...     Function('wrap', ['*args', '**kwargs']), {args: 'atuple'})
        'wrap(a=6, b=7, *atuple)'

    When varargs are present all preceding arguments are positioned, not named.
        >>> call_as_string_for('sum', {'x': serialize(1), 'rest': serialize((2, 3))},
        ...     Function('sum', ['x', '*rest']))
        'sum(1, 2, 3)'

    When argument type requires import, the import is present in the imports list.
        >>> m = Module(None, 'myclasses')
        >>> cs = call_as_string_for('display',
        ...     {'obj': UserObject(None, Class('MyWindow', module=m))},
        ...     Function('display', ['obj']))
        >>> cs
        'display(MyWindow())'
        >>> cs.imports
        set([('myclasses', 'MyWindow')])
    """
    positional_args = []
    keyword_args = []
    vararg = None
    kwarg = None

    def getvalue(argname):
        return args[argname.lstrip("*")]

    skipped_an_arg = False
    for argname in arguments_of(definition):
        try:
            value = getvalue(argname)
            if argname.startswith("**"):
                if value in assigned_names.keys():
                    kwarg = CodeString("**%s" % assigned_names[value])
                else:
                    for karg, kvalue in map_as_kwargs(value):
                        valuecs = constructor_as_string(kvalue, assigned_names)
                        keyword_args.append(combine(karg, valuecs, "%s=%s"))
            elif argname.startswith("*"):
                if value in assigned_names.keys():
                    vararg = CodeString("*%s" % assigned_names[value])
                else:
                    code_strings = get_contained_objects_info(
                        value, assigned_names)
                    positional_args.extend(code_strings)
            else:
                constructor = constructor_as_string(value, assigned_names)
                if skipped_an_arg:
                    keyword_args.append(combine(argname, constructor, "%s=%s"))
                else:
                    positional_args.append(constructor)
        except KeyError:
            skipped_an_arg = True

    arguments = join(
        ', ',
        filter(None, (positional_args + keyword_args + [vararg] + [kwarg])))
    return combine(object_name, arguments, "%s(%s)")
コード例 #13
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
def attribute_assignment_line(left, right, already_assigned_names):
    try:
        constructor = CodeString(already_assigned_names[right])
    except KeyError:
        constructor = constructor_as_string(right, already_assigned_names)
    return combine(left, constructor, "%s = %s")
コード例 #14
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
def add_newline(code_string):
    return combine(code_string, "\n")
コード例 #15
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
 def raises_assertion(self, exception, call):
     return addimport(combine(exception, call, "assert_raises(%s, %s)"),
                      ('nose.tools', 'assert_raises'))
コード例 #16
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
 def equal_assertion(self, expected, actual):
     return addimport(combine(expected, actual, "assert_equal(%s, %s)"),
                      ('nose.tools', 'assert_equal'))
コード例 #17
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
 def raises_assertion(self, exception, call):
     return combine(exception, call, "self.assertRaises(%s, %s)")
コード例 #18
0
def generate_test_contents(events, template):
    contents = CodeString("")
    all_uncomplete = False
    already_assigned_names = {}
    for event in events:
        if isinstance(event, Assign):
            line = variable_assignment_line(event.name, event.obj,
                                            already_assigned_names)
        elif isinstance(event, BindingChange):
            if event.name.obj in already_assigned_names.keys():
                already_assigned_names[
                    event.obj] = code_string_from_object_attribute_reference(
                        event.name, already_assigned_names)
            continue  # This is not a real test line, so just go directly to the next line.
        elif isinstance(event, EqualAssertionLine):
            expected = constructor_as_string(event.expected,
                                             already_assigned_names)
            if isinstance(event.actual, (Call, MethodCallContext)):
                actual = call_in_test(event.actual, already_assigned_names)
            elif isinstance(event.actual, ModuleVariableReference):
                actual = code_string_from_module_variable_reference(
                    event.actual)
            elif isinstance(event.actual, ObjectAttributeReference):
                actual = code_string_from_object_attribute_reference(
                    event.actual, already_assigned_names)
            elif isinstance(event.actual, str):
                actual = CodeString(event.actual)
            else:
                actual = constructor_as_string(event.actual,
                                               already_assigned_names)
            if expected.uncomplete:
                expected = type_as_string(event.expected)
                actual = type_of(actual)
            line = template.equal_assertion(expected, actual)
        elif isinstance(event, GeneratorAssertionLine):
            call = event.generator_call
            yields = generator_object_yields(call)
            expected = constructor_as_string(yields, already_assigned_names)
            actual = call_in_test(call, already_assigned_names)
            if expected.uncomplete:
                expected = type_as_string(yields)
                actual = map_types(actual)
                actual = addimport(actual, 'types')
            line = template.equal_assertion(expected, actual)
        elif isinstance(event, RaisesAssertionLine):
            actual = call_in_test(event.call, already_assigned_names)
            actual = in_lambda(actual)
            if is_serialized_string(event.expected_exception):
                exception = todo_value(event.expected_exception.reconstructor)
            else:
                exception = CodeString(event.expected_exception.type_name)
                exception = addimport(exception,
                                      event.expected_exception.type_import)
            line = template.raises_assertion(exception, actual)
        elif isinstance(event, CommentLine):
            line = CodeString(event.comment)
        elif isinstance(event, SkipTestLine):
            line = template.skip_test()
        elif isinstance(event, EqualAssertionStubLine):
            line = template.equal_assertion(
                CodeString('expected', uncomplete=True), event.actual)
        elif isinstance(event, BuiltinMethodWithPositionArgsSideEffect):
            # All objects affected by side effects are named.
            object_name = already_assigned_names[event.obj]
            line = call_as_string_for(
                "%s.%s" % (object_name, event.definition.name),
                event.args_mapping(), event.definition, already_assigned_names)
        elif isinstance(event, AttributeRebind):
            # All objects affected by side effects are named.
            object_name = already_assigned_names[event.obj]
            line = attribute_assignment_line(
                "%s.%s" % (object_name, event.name), event.value,
                already_assigned_names)

        else:
            raise TypeError(
                "Don't know how to generate test contents for event %r." %
                event)
        if line.uncomplete:
            all_uncomplete = True
        if all_uncomplete and not isinstance(event, SkipTestLine):
            line = combine("# ", line)
        contents = combine(contents, add_newline(line))
    return contents
コード例 #19
0
 def equal_assertion(self, expected, actual):
     return combine(expected, actual, "self.assertEqual(%s, %s)")
コード例 #20
0
 def raises_assertion(self, exception, call):
     return addimport(combine(exception, call, "assert_raises(%s, %s)"),
                      ('nose.tools', 'assert_raises'))
コード例 #21
0
 def equal_assertion(self, expected, actual):
     return addimport(combine(expected, actual, "assert_equal(%s, %s)"),
                      ('nose.tools', 'assert_equal'))
コード例 #22
0
ファイル: builder.py プロジェクト: enlite93/pythoscope
def generate_test_contents(events, template):
    contents = CodeString("")
    all_uncomplete = False
    already_assigned_names = {}
    for event in events:
        if isinstance(event, Assign):
            line = variable_assignment_line(event.name, event.obj, already_assigned_names)
        elif isinstance(event, BindingChange):
            if event.name.obj in already_assigned_names.keys():
                already_assigned_names[event.obj] = code_string_from_object_attribute_reference(event.name, already_assigned_names)
            continue # This is not a real test line, so just go directly to the next line.
        elif isinstance(event, EqualAssertionLine):
            expected = constructor_as_string(event.expected, already_assigned_names)
            if isinstance(event.actual, (Call, MethodCallContext)):
                actual = call_in_test(event.actual, already_assigned_names)
            elif isinstance(event.actual, ModuleVariableReference):
                actual = code_string_from_module_variable_reference(event.actual)
            elif isinstance(event.actual, ObjectAttributeReference):
                actual = code_string_from_object_attribute_reference(event.actual, already_assigned_names)
            elif isinstance(event.actual, str):
                actual = CodeString(event.actual)
            else:
                actual = constructor_as_string(event.actual, already_assigned_names)
            if expected.uncomplete:
                expected = type_as_string(event.expected)
                actual = type_of(actual)
            line = template.equal_assertion(expected, actual)
        elif isinstance(event, GeneratorAssertionLine):
            call = event.generator_call
            yields = generator_object_yields(call)
            expected = constructor_as_string(yields, already_assigned_names)
            actual = call_in_test(call, already_assigned_names)
            if expected.uncomplete:
                expected = type_as_string(yields)
                actual = map_types(actual)
                actual = addimport(actual, 'types')
            line = template.equal_assertion(expected, actual)
        elif isinstance(event, RaisesAssertionLine):
            actual = call_in_test(event.call, already_assigned_names)
            actual = in_lambda(actual)
            if is_serialized_string(event.expected_exception):
                exception = todo_value(event.expected_exception.reconstructor)
            else:
                exception = CodeString(event.expected_exception.type_name)
                exception = addimport(exception, event.expected_exception.type_import)
            line = template.raises_assertion(exception, actual)
        elif isinstance(event, CommentLine):
            line = CodeString(event.comment)
        elif isinstance(event, SkipTestLine):
            line = template.skip_test()
        elif isinstance(event, EqualAssertionStubLine):
            line = template.equal_assertion(CodeString('expected', uncomplete=True), event.actual)
        elif isinstance(event, BuiltinMethodWithPositionArgsSideEffect):
            # All objects affected by side effects are named.
            object_name = already_assigned_names[event.obj]
            line = call_as_string_for("%s.%s" % (object_name, event.definition.name),
                                      event.args_mapping(),
                                      event.definition,
                                      already_assigned_names)
        elif isinstance(event, AttributeRebind):
            # All objects affected by side effects are named.
            object_name = already_assigned_names[event.obj]
            line = attribute_assignment_line("%s.%s" % (object_name, event.name),
                                             event.value,
                                             already_assigned_names)

        else:
            raise TypeError("Don't know how to generate test contents for event %r." % event)
        if line.uncomplete:
            all_uncomplete = True
        if all_uncomplete and not isinstance(event, SkipTestLine):
            line = combine("# ", line)
        contents = combine(contents, add_newline(line))
    return contents
コード例 #23
0
def add_newline(code_string):
    return combine(code_string, "\n")
コード例 #24
0
def get_objects_mapping_info(mapping, assigned_names):
    for key, value in mapping:
        keycs = constructor_as_string(key, assigned_names)
        valuecs = constructor_as_string(value, assigned_names)
        yield combine(keycs, valuecs, "%s: %s")