Exemplo n.º 1
0
    def _processVisit(self, node, loop_name):
        if self.loop_counter > self.loop_target:
            self.is_mutating = False

        if self.is_mutating:
            self.loop_counter += 1

            if self.loop_counter == self.loop_target:
                self.has_mutation = True
                start_lineno = node.lineno
                body_lineno = node.body[0].lineno
                line = self.source_lines[node.lineno + self.lineno_modifier - 1]

                if node.lineno == body_lineno:
                    # For those loop-statements with body on the same line
                    end_lineno = node.lineno + 1
                    body_indentation = self.indentation(line) + '    '
                    if isinstance(node.body[0], ast.Pass):
                        node.body.pop(0)
                else:
                    end_lineno = body_lineno
                    body_indentation = self.indentation(self.source_lines[body_lineno + self.lineno_modifier - 1])
                    if isinstance(node.body[0], ast.Pass):
                        n = node.body.pop(0)
                        end_lineno += 1

                node.body.insert(0, ast.parse('if mutest_statement_reached() % 2 == 0: continue'))

                new_lines = [ ]
                if loop_name == 'for':
                    new_lines.append(self.indentation(line) + 'for ' + codegen.to_source(node.target) + ' in ' + codegen.to_source(node.iter) + ':\n')
                else:
                    new_lines.append(self.indentation(line) + 'while ' + codegen.to_source(node.test) + ':\n')

                new_lines.append(body_indentation + 'if mutest_statement_reached() % 2 == 0: continue\n')
                if node.lineno == body_lineno:
                    for n in node.body[1:]: # The first line "if mutest_statement_reached() % 2 == 0: continue" is already inserted
                        new_lines.append(body_indentation + codegen.to_source(n) + '\n')

                indent = None
                for i in range(start_lineno, end_lineno):
                    indent = self.comment_line(i + self.lineno_modifier, indent)

                self.source_lines[end_lineno-1+self.lineno_modifier:end_lineno-1+self.lineno_modifier] = new_lines
                self.lineno_modifier += len(new_lines)

        self.generic_visit(node)
        return node
Exemplo n.º 2
0
    def visit_If(self, node):
        if self.if_counter > self.if_target:
            self.is_mutating = False

        if self.is_mutating:
            self.if_counter += 1

            if len(node.orelse) == 1 and isinstance(node.orelse[0], ast.If):
                self.ifelse_set.add(node.orelse[0])

            if self.if_counter == self.if_target:
                new_test = ast.UnaryOp(op=ast.Not(), operand=node.test)
                new_node = ast.copy_location(
                    ast.If(
                        test=ast.BoolOp(op=ast.Or(), values=[self.prepare_mutest_reached_node(), new_test]),
                        body=node.body,
                        orelse=node.orelse,
                    ),
                    node,
                )

                self.has_mutation = True
                is_elif = node in self.ifelse_set

                if node.lineno == node.body[0].lineno:
                    # For those if-statements with body on the same line
                    line = self.source_lines[node.lineno + self.lineno_modifier - 1]
                    new_line = (
                        self.indentation(line) + ("elif " if is_elif else "if ") + codegen.to_source(new_test) + ": "
                    )
                    child_nodes = node.body[:]
                    while child_nodes:
                        n = child_nodes.pop(0)
                        new_line = new_line + codegen.to_source(n) + ("; " if child_nodes else "")
                    new_line = new_line + "\n"
                    self.comment_line(node.lineno + self.lineno_modifier)
                    self.source_lines.insert(node.lineno + self.lineno_modifier, new_line)
                    self.lineno_modifier += 1
                else:
                    end_lineno = node.body[0].lineno
                    for start_lineno in range(end_lineno - 1, 0, -1):
                        m = (self.IFELSE_PAT if is_elif else self.IF_PAT).search(
                            self.source_lines[start_lineno + self.lineno_modifier - 1] + " "
                        )
                        if m:
                            break

                    # Standard if-statements with body on separate lines, or testing conditions over multiple lines
                    indent = None
                    for i in range(start_lineno, end_lineno):
                        indent = self.comment_line(i + self.lineno_modifier, indent)
                    line = self.source_lines[node.lineno + self.lineno_modifier - 1]
                    new_line = (
                        self.indentation(line) + ("elif " if is_elif else "if ") + codegen.to_source(new_test) + ":\n"
                    )
                    self.source_lines.insert(end_lineno + self.lineno_modifier - 1, new_line)
                    self.lineno_modifier += 1

                self.generic_visit(new_node)
                return new_node

        self.generic_visit(node)
        return node
Exemplo n.º 3
0
    def _f():
        source_filename = os.path.join(os.path.dirname(__file__), 'depfiles', test_name + '.py')
        with open(source_filename, 'r') as source_fh:
            source_lines = source_fh.readlines()

        test_func_name, lineno = source_lines[0][1:].strip().split(':')
        test_func_lineno = int(lineno)

        buf = StringIO(codegen.to_source(ast.parse(''.join(source_lines))))
        orig_ast_lines = buf.readlines()
        buf.close()

        diffs_filename = os.path.join(os.path.dirname(__file__), 'depfiles', test_name + '.diffs')
        diffs_list, _diff = [ ], [ ]
        with open(diffs_filename, 'r') as diff_fh:
            while True:
                line = diff_fh.readline()
                if not line:
                    break
                line = line.rstrip()
                if line[:2] == '##':
                    if _diff:
                        diffs_list.append(_diff)
                        _diff = [ ]
                elif line:
                    _diff.append(line)

        if _diff:
            diffs_list.append(_diff)
        del _diff

        asts_filename = os.path.join(os.path.dirname(__file__), 'depfiles', test_name + '.asts')
        asts_list, _ast = [ ], [ ]
        with open(asts_filename, 'r') as ast_fh:
            while True:
                line = ast_fh.readline()
                if not line:
                    break
                line = line.rstrip()
                if line[:2] == '##':
                    if _ast:
                        asts_list.append(_ast)
                        _ast = [ ]
                elif line:
                    _ast.append(line)

        if _ast:
            asts_list.append(_ast)
        del _ast

        mutator = mutator_klass()
        for asts, diff, result in itertools.izip_longest(asts_list, diffs_list, mutator.mutate(source_filename, test_func_name, test_func_lineno), fillvalue = None):
            if not result:
                print 'Failed. Missing diff results'
                print '==========================='
                print 'Expecting diff'
                print '\n'.join(diff)
                assert False

            test_id, mutated_lines, mutated_ast = result
            mutated_diff = filter(lambda s: s and s[0] in ( '+', '-' ) and s != '---' and s != '+++', map(lambda s: s.rstrip(), difflib.unified_diff(source_lines, mutated_lines)))

            if not diff:
                print test_id, 'has failed. No corresponding diff found'
                print '==========================='
                print 'Result diff'
                print '\n'.join(mutated_diff)
                assert False

            if list(difflib.unified_diff(diff, mutated_diff)):
                print
                print test_id, 'has failed to match diff'
                print '==========================='
                print 'Expecting diff'
                print '\n'.join(diff)
                print 'Result diff'
                print '\n'.join(mutated_diff)
                print
                assert False

            buf = StringIO(codegen.to_source(mutated_ast))
            mutated_lines = buf.readlines()
            buf.close()
            mutated_asts = filter(lambda s: s and s[0] in ( '+', '-' ) and s != '---' and s != '+++', map(lambda s: s.rstrip(), difflib.unified_diff(orig_ast_lines, mutated_lines)))

            if not asts:
                print test_id, 'has failed. No corresponding ast found'
                print '==========================='
                print 'Result ast'
                print '\n'.join(mutated_asts)
                assert False

            if list(difflib.unified_diff(asts, mutated_asts)):
                print
                print test_id, 'has failed to match ast'
                print '==========================='
                print 'Expecting ast'
                print '\n'.join(asts)
                print 'Result ast'
                print '\n'.join(mutated_asts)
                print
                assert False
Exemplo n.º 4
0
    def _f():
        source_filename = os.path.join(os.path.dirname(__file__), "depfiles", test_name + ".py")
        with open(source_filename, "r") as source_fh:
            source_lines = source_fh.readlines()

        test_func_name, lineno = source_lines[0][1:].strip().split(":")
        test_func_lineno = int(lineno)

        buf = StringIO(codegen.to_source(ast.parse("".join(source_lines))))
        orig_ast_lines = buf.readlines()
        buf.close()

        diffs_filename = os.path.join(os.path.dirname(__file__), "depfiles", test_name + ".diffs")
        diffs_list, _diff = [], []
        with open(diffs_filename, "r") as diff_fh:
            while True:
                line = diff_fh.readline()
                if not line:
                    break
                line = line.rstrip()
                if line[:2] == "##":
                    if _diff:
                        diffs_list.append(_diff)
                        _diff = []
                elif line:
                    _diff.append(line)

        if _diff:
            diffs_list.append(_diff)
        del _diff

        asts_filename = os.path.join(os.path.dirname(__file__), "depfiles", test_name + ".asts")
        asts_list, _ast = [], []
        with open(asts_filename, "r") as ast_fh:
            while True:
                line = ast_fh.readline()
                if not line:
                    break
                line = line.rstrip()
                if line[:2] == "##":
                    if _ast:
                        asts_list.append(_ast)
                        _ast = []
                elif line:
                    _ast.append(line)

        if _ast:
            asts_list.append(_ast)
        del _ast

        mutator = mutator_klass()
        for asts, diff, result in itertools.izip_longest(
            asts_list, diffs_list, mutator.mutate(source_filename, test_func_name, test_func_lineno), fillvalue=None
        ):
            if not result:
                print "Failed. Missing diff results"
                print "==========================="
                print "Expecting diff"
                print "\n".join(diff)
                assert False

            test_id, mutated_lines, mutated_ast = result
            mutated_diff = filter(
                lambda s: s and s[0] in ("+", "-") and s != "---" and s != "+++",
                map(lambda s: s.rstrip(), difflib.unified_diff(source_lines, mutated_lines)),
            )

            if not diff:
                print test_id, "has failed. No corresponding diff found"
                print "==========================="
                print "Result diff"
                print "\n".join(mutated_diff)
                assert False

            if list(difflib.unified_diff(diff, mutated_diff)):
                print
                print test_id, "has failed to match diff"
                print "==========================="
                print "Expecting diff"
                print "\n".join(diff)
                print "Result diff"
                print "\n".join(mutated_diff)
                print
                assert False

            buf = StringIO(codegen.to_source(mutated_ast))
            mutated_lines = buf.readlines()
            buf.close()
            mutated_asts = filter(
                lambda s: s and s[0] in ("+", "-") and s != "---" and s != "+++",
                map(lambda s: s.rstrip(), difflib.unified_diff(orig_ast_lines, mutated_lines)),
            )

            if not asts:
                print test_id, "has failed. No corresponding ast found"
                print "==========================="
                print "Result ast"
                print "\n".join(mutated_asts)
                assert False

            if list(difflib.unified_diff(asts, mutated_asts)):
                print
                print test_id, "has failed to match ast"
                print "==========================="
                print "Expecting ast"
                print "\n".join(asts)
                print "Result ast"
                print "\n".join(mutated_asts)
                print
                assert False
Exemplo n.º 5
0
    def _processVisit(self, node, loop_name):
        if self.loop_counter > self.loop_target:
            self.is_mutating = False

        if self.is_mutating:
            self.loop_counter += 1

            if self.loop_counter == self.loop_target:
                self.has_mutation = True
                start_lineno = node.lineno
                body_lineno = node.body[0].lineno
                line = self.source_lines[node.lineno + self.lineno_modifier -
                                         1]

                if node.lineno == body_lineno:
                    # For those loop-statements with body on the same line
                    end_lineno = node.lineno + 1
                    body_indentation = self.indentation(line) + '    '
                    if isinstance(node.body[0], ast.Pass):
                        node.body.pop(0)
                else:
                    end_lineno = body_lineno
                    body_indentation = self.indentation(
                        self.source_lines[body_lineno + self.lineno_modifier -
                                          1])
                    if isinstance(node.body[0], ast.Pass):
                        n = node.body.pop(0)
                        end_lineno += 1

                node.body.insert(
                    0,
                    ast.parse(
                        'if mutest_statement_reached() % 2 == 0: continue'))

                new_lines = []
                if loop_name == 'for':
                    new_lines.append(
                        self.indentation(line) + 'for ' +
                        codegen.to_source(node.target) + ' in ' +
                        codegen.to_source(node.iter) + ':\n')
                else:
                    new_lines.append(
                        self.indentation(line) + 'while ' +
                        codegen.to_source(node.test) + ':\n')

                new_lines.append(
                    body_indentation +
                    'if mutest_statement_reached() % 2 == 0: continue\n')
                if node.lineno == body_lineno:
                    for n in node.body[
                            1:]:  # The first line "if mutest_statement_reached() % 2 == 0: continue" is already inserted
                        new_lines.append(body_indentation +
                                         codegen.to_source(n) + '\n')

                indent = None
                for i in range(start_lineno, end_lineno):
                    indent = self.comment_line(i + self.lineno_modifier,
                                               indent)

                self.source_lines[end_lineno - 1 +
                                  self.lineno_modifier:end_lineno - 1 +
                                  self.lineno_modifier] = new_lines
                self.lineno_modifier += len(new_lines)

        self.generic_visit(node)
        return node
Exemplo n.º 6
0
    def visit_If(self, node):
        if self.if_counter > self.if_target:
            self.is_mutating = False

        if self.is_mutating:
            self.if_counter += 1

            if len(node.orelse) == 1 and isinstance(node.orelse[0], ast.If):
                self.ifelse_set.add(node.orelse[0])

            if self.if_counter == self.if_target:
                new_test = ast.UnaryOp(op=ast.Not(), operand=node.test)
                new_node = ast.copy_location(
                    ast.If(test=ast.BoolOp(
                        op=ast.Or(),
                        values=[self.prepare_mutest_reached_node(), new_test]),
                           body=node.body,
                           orelse=node.orelse), node)

                self.has_mutation = True
                is_elif = node in self.ifelse_set

                if node.lineno == node.body[0].lineno:
                    # For those if-statements with body on the same line
                    line = self.source_lines[node.lineno +
                                             self.lineno_modifier - 1]
                    new_line = self.indentation(line) + (
                        'elif ' if is_elif else
                        'if ') + codegen.to_source(new_test) + ': '
                    child_nodes = node.body[:]
                    while child_nodes:
                        n = child_nodes.pop(0)
                        new_line = new_line + codegen.to_source(n) + (
                            '; ' if child_nodes else '')
                    new_line = new_line + '\n'
                    self.comment_line(node.lineno + self.lineno_modifier)
                    self.source_lines.insert(
                        node.lineno + self.lineno_modifier, new_line)
                    self.lineno_modifier += 1
                else:
                    end_lineno = node.body[0].lineno
                    for start_lineno in range(end_lineno - 1, 0, -1):
                        m = (self.IFELSE_PAT if is_elif else
                             self.IF_PAT).search(self.source_lines[
                                 start_lineno + self.lineno_modifier - 1] +
                                                 ' ')
                        if m:
                            break

                    # Standard if-statements with body on separate lines, or testing conditions over multiple lines
                    indent = None
                    for i in range(start_lineno, end_lineno):
                        indent = self.comment_line(i + self.lineno_modifier,
                                                   indent)
                    line = self.source_lines[node.lineno +
                                             self.lineno_modifier - 1]
                    new_line = self.indentation(line) + (
                        'elif ' if is_elif else
                        'if ') + codegen.to_source(new_test) + ':\n'
                    self.source_lines.insert(
                        end_lineno + self.lineno_modifier - 1, new_line)
                    self.lineno_modifier += 1

                self.generic_visit(new_node)
                return new_node

        self.generic_visit(node)
        return node