Example #1
0
    def get_multiline(file, filename, text, annotation_start, annotation_end,
                      position):
        """
        Gets sourcerange and end position of an annotation that can span
        multiple lines.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param annotation_start:
            The string specifying the start of the annotation.
        :param annotation_end:
            The string specifying the end of the annotation.
        :param position:
            An integer identifying the position where the annotation started.
        :return:
            A SourceRange object holding the range of the multi-line annotation
            and the end_position of the annotation as an integer.
        """
        end_end = get_end_position(annotation_end, text,
                                   position + len(annotation_start) - 1)
        if end_end == -1:
            _range = SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position))
            raise NoCloseError(annotation_start, _range)

        return (SourceRange.from_absolute_position(
            filename, AbsolutePosition(file, position),
            AbsolutePosition(file, end_end)), end_end)
 def test_combined_strings(self):
     file_text = ['"some string #with comment"\n',
                  '"""\n',
                  "now a multiline string ''' <- this one not\n",
                  '"""\n',
                  '"""\n'
                  'another comment # rather harmless\n',
                  '"""\n']
     string1_start = 0
     string1_end = len(file_text[0]) - 2
     string1 = SourceRange.from_absolute_position(
                                 "F",
                                 AbsolutePosition(file_text, string1_start),
                                 AbsolutePosition(file_text, string1_end))
     string2_start = string1_end+2
     text = ''.join(file_text)
     string2_end = text.find('"""', string2_start + 1) + 2
     #+2 for length of """
     string2 = SourceRange.from_absolute_position(
                                 "F",
                                 AbsolutePosition(file_text, string2_start),
                                 AbsolutePosition(file_text, string2_end))
     string3_start = text.find('"""', string2_end + 1)
     string3_end = text.find('"""', string3_start + 1) + 2
     #+2 for length of """
     string3 = SourceRange.from_absolute_position(
                                 "F",
                                 AbsolutePosition(file_text, string3_start),
                                 AbsolutePosition(file_text, string3_end))
     with execute_bear(self.python_uut, "F", file_text) as results:
         self.assertIn(string1, results[0].contents['strings'])
         self.assertIn(string2, results[0].contents['strings'])
         self.assertIn(string3, results[0].contents['strings'])
         self.assertEqual(results[0].contents['comments'], ())
 def test_combined_strings(self):
     file_text = [
         '"some string #with comment"\n', '"""\n',
         "now a multiline string ''' <- this one not\n", '"""\n', '"""\n'
         'another comment # rather harmless\n', '"""\n'
     ]
     string1_start = 0
     string1_end = len(file_text[0]) - 2
     string1 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string1_start),
         AbsolutePosition(file_text, string1_end))
     string2_start = string1_end + 2
     text = ''.join(file_text)
     string2_end = text.find('"""', string2_start + 1) + 2
     #+2 for length of """
     string2 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string2_start),
         AbsolutePosition(file_text, string2_end))
     string3_start = text.find('"""', string2_end + 1)
     string3_end = text.find('"""', string3_start + 1) + 2
     #+2 for length of """
     string3 = SourceRange.from_absolute_position(
         "F", AbsolutePosition(file_text, string3_start),
         AbsolutePosition(file_text, string3_end))
     with execute_bear(self.python_uut, "F", file_text) as results:
         self.assertIn(string1, results[0].contents['strings'])
         self.assertIn(string2, results[0].contents['strings'])
         self.assertIn(string3, results[0].contents['strings'])
         self.assertEqual(results[0].contents['comments'], ())
Example #4
0
    def get_singleline_strings(file, filename, text, string_start, string_end,
                               position):
        """
        Gets sourcerange of a single-line string and its end position.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param string_start:
            The string which specifies how a string starts.
        :param string_end:
            The string which specifies how a string ends.
        :position:
            An integer identifying the position where the string started.
        :return:
            A SourceRange object identifying the range of the single-line
            string and the end_position of the string as an integer.
        """
        end_position = get_end_position(string_end, text,
                                        position + len(string_start) - 1)
        newline = get_end_position("\n", text, position)
        if newline == -1:
            newline = len(text)
        if end_position == -1:
            _range = SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position))
            raise NoCloseError(string_start, _range)
        if newline > end_position:
            return (SourceRange.from_absolute_position(
                filename, AbsolutePosition(file, position),
                AbsolutePosition(file, end_position)), end_position)
Example #5
0
    def test_from_absolute_position(self):
        text = ('a\n', 'b\n')
        start = AbsolutePosition(text, 0)
        end = AbsolutePosition(text, 2)

        uut = SourceRange.from_absolute_position('F', start, end)
        compare = SourceRange.from_values('F', 1, 1, 2, 1)
        self.assertEqual(uut, compare)

        uut = SourceRange.from_absolute_position('F', start, None)
        compare = SourceRange(SourcePosition('F', 1, 1), None)
        self.assertEqual(uut, compare)
Example #6
0
    def test_from_absolute_position(self):
        text = ("a\n", "b\n")
        start = AbsolutePosition(text, 0)
        end = AbsolutePosition(text, 2)

        uut = SourceRange.from_absolute_position("F", start, end)
        compare = SourceRange.from_values("F", 1, 1, 2, 1)
        self.assertEqual(uut, compare)

        uut = SourceRange.from_absolute_position("F", start, None)
        compare = SourceRange(SourcePosition("F", 1, 1), None)
        self.assertEqual(uut, compare)
 def test_string_with_comments(self):
     text = ["some #comment\n", "with 'string' in  next line"]
     comment_start = text[0].find('#')
     comment_end = len(text[0]) - 1
     string_start = ''.join(text).find("'")
     string_end = ''.join(text).find("'", string_start + 1)
     compare = [(SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, string_start),
         AbsolutePosition(text, string_end)), ),
                (SourceRange.from_absolute_position(
                    "F", AbsolutePosition(text, comment_start),
                    AbsolutePosition(text, comment_end)), )]
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare[0])
         self.assertEqual(result[0].contents['comments'], compare[1])
Example #8
0
    def get_singleline_comment(file, filename, text, comment, position):
        """
        Gets Sourcerange of a single-line comment where the start is the
        start of comment and the end is the end of line.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param comment:
            The string which specifies the comment.
        :position:
            An integer identifying the position where the string started.
        :return:
            A SourceRange object identifying the range of the single-line
            comment and the end_position of the comment as an integer.
        """
        end_position = get_end_position('\n',
                                        text,
                                        position + len(comment) - 1)
        if end_position == -1:
            end_position = len(text) - 1
        return (SourceRange.from_absolute_position(
                    filename,
                    AbsolutePosition(file, position),
                    AbsolutePosition(file, end_position)),
                end_position)
 def test_string_with_comments(self):
     text = ["some #comment\n", "with 'string' in  next line"]
     comment_start = text[0].find('#')
     comment_end = len(text[0]) - 1
     string_start = ''.join(text).find("'")
     string_end = ''.join(text).find("'", string_start + 1)
     compare = [(SourceRange.from_absolute_position(
                             "F",
                             AbsolutePosition(text, string_start),
                             AbsolutePosition(text, string_end)),),
                (SourceRange.from_absolute_position(
                             "F",
                             AbsolutePosition(text, comment_start),
                             AbsolutePosition(text, comment_end)),)]
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare[0])
         self.assertEqual(result[0].contents['comments'], compare[1])
 def test_multiline_comment(self):
     text = ["some string /*within \n", "'multiline comment'*/"]
     compare = (SourceRange.from_absolute_position(
                         "F",
                         AbsolutePosition(text, text[0].find('/*')),
                         AbsolutePosition(text, len(''.join(text)) - 1)),)
     with execute_bear(self.c_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
 def test_single_line_comment(self):
     text = ["some #coment with 'string'\n", "and next line"]
     compare = (SourceRange.from_absolute_position(
                                 "F",
                                 AbsolutePosition(text, text[0].find('#')),
                                 AbsolutePosition(text, len(text[0]) - 1)),)
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
 def test_multiline_string(self):
     text = ["'''multiline string, #comment within it'''\n"]
     compare = (SourceRange.from_absolute_position(
                     "F",
                     AbsolutePosition(text, 0),
                     AbsolutePosition(text, len(text[0])-2)),)
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
 def test_single_line_string(self):
     text = ["'from start till the end with #comments'\n", ]
     compare = (SourceRange.from_absolute_position(
                                 "F",
                                 AbsolutePosition(text, 0),
                                 AbsolutePosition(text, len(text[0]) - 2)),)
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
    def get_specified_block_range(self,
                                  file,
                                  filename,
                                  open_specifier,
                                  close_specifier,
                                  annotation_dict):
        """
        Gets a sourceranges of all the indentation blocks present inside the
        file.

        :param file:            File that needs to be checked in the form of
                                a list of strings.
        :param filename:        Name of the file that needs to be checked.
        :param open_specifier:  A character or string indicating that the
                                block has begun.
        :param close_specifier: A character or string indicating that the block
                                has ended.
        :param annotation_dict: A dictionary containing sourceranges of all the
                                strings and comments within a file.
        :return:                A tuple whith the first source range being
                                the range of the outermost indentation while
                                last being the range of the most
                                nested/innermost indentation.
                                Equal level indents appear in the order of
                                first encounter or left to right.
        """
        ranges = []

        open_pos = list(self.get_valid_sequences(
            file, open_specifier, annotation_dict))
        close_pos = list(self.get_valid_sequences(
            file, close_specifier, annotation_dict))

        to_match = len(open_pos) - 1
        while to_match >= 0:
            close_index = 0
            while close_index < len(close_pos):
                if(open_pos[to_match].position
                   <= close_pos[close_index].position):
                    ranges.append(
                        SourceRange.from_absolute_position(
                            filename,
                            open_pos[to_match],
                            close_pos[close_index]))
                    close_pos.remove(close_pos[close_index])
                    open_pos.remove(open_pos[to_match])
                    to_match -= 1
                    break
                close_index += 1
            if((len(close_pos) == 0 and to_match != -1) or
               (len(close_pos) != 0 and to_match == -1)):
                # None to specify unmatched indents
                raise UnmatchedIndentError(open_specifier, close_specifier)

        # Ranges are returned in the order of least nested to most nested
        # and also on the basis of which come first
        return tuple(ranges)[::-1]
Example #15
0
 def test_multiline_comment(self):
     text = ["some string /*within \n", "'multiline comment'*/"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, text[0].find('/*')),
         AbsolutePosition(text,
                          len(''.join(text)) - 1)), )
     with execute_bear(self.c_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
Example #16
0
 def test_single_line_comment(self):
     text = ["some #coment with 'string'\n", "and next line"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, text[0].find('#')),
         AbsolutePosition(text,
                          len(text[0]) - 1)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], ())
         self.assertEqual(result[0].contents['comments'], compare)
Example #17
0
 def test_multiline_string(self):
     text = ["'''multiline string, #comment within it'''\n"]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, 0),
         AbsolutePosition(text,
                          len(text[0]) - 2)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
Example #18
0
 def test_single_line_string(self):
     text = [
         "'from start till the end with #comments'\n",
     ]
     compare = (SourceRange.from_absolute_position(
         "F", AbsolutePosition(text, 0),
         AbsolutePosition(text,
                          len(text[0]) - 2)), )
     with execute_bear(self.python_uut, "F", text) as result:
         self.assertEqual(result[0].contents['strings'], compare)
         self.assertEqual(result[0].contents['comments'], ())
    def get_singleline_strings(file,
                               filename,
                               text,
                               string_start,
                               string_end,
                               position):
        """
        Gets sourcerange of a single-line string and its end position.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param string_start:
            The string which specifies how a string starts.
        :param string_end:
            The string which specifies how a string ends.
        :position:
            An integer identifying the position where the string started.
        :return:
            A SourceRange object identifying the range of the single-line
            string and the end_position of the string as an integer.
        """
        end_position = get_end_position(string_end,
                                        text,
                                        position + len(string_start) - 1)
        newline = get_end_position('\n', text, position)
        if newline == -1:
            newline = len(text)
        if end_position == -1:
            _range = SourceRange.from_absolute_position(
                filename,
                AbsolutePosition(file, position))
            raise NoCloseError(string_start, _range)
        if newline > end_position:
            return (SourceRange.from_absolute_position(
                        filename,
                        AbsolutePosition(file, position),
                        AbsolutePosition(file, end_position)),
                    end_position)
Example #20
0
    def test_multiline_comment(self):
        text = ['some string /*within \n', "'multiline comment'*/"]
        compare = (SourceRange.from_absolute_position(
            'F', AbsolutePosition(text, text[0].find('/*')),
            AbsolutePosition(text,
                             len(''.join(text)) - 1)), )
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].contents['strings'], ())
            self.assertEqual(result[0].contents['comments'], compare)

        text = ['/*Multiline which does not end']
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].message, '/* has no closure')
    def test_multiline_comment(self):
        text = ['some string /*within \n', "'multiline comment'*/"]
        compare = (SourceRange.from_absolute_position(
                            'F',
                            AbsolutePosition(text, text[0].find('/*')),
                            AbsolutePosition(text, len(''.join(text)) - 1)),)
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].contents['strings'], ())
            self.assertEqual(result[0].contents['comments'], compare)

        text = ['/*Multiline which does not end']
        with execute_bear(self.c_uut, 'F', text) as result:
            self.assertEqual(result[0].message, '/* has no closure')
    def get_multiline(file,
                      filename,
                      text,
                      annotation_start,
                      annotation_end,
                      position):
        """
        Gets sourcerange and end position of an annotation that can span
        multiple lines.

        :param file:
            A tuple of strings, with each string being a line in the file.
        :param filename:
            The name of the file.
        :param annotation_start:
            The string specifying the start of the annotation.
        :param annotation_end:
            The string specifying the end of the annotation.
        :param position:
            An integer identifying the position where the annotation started.
        :return:
            A SourceRange object holding the range of the multi-line annotation
            and the end_position of the annotation as an integer.
        """
        end_end = get_end_position(annotation_end,
                                   text,
                                   position + len(annotation_start) - 1)
        if end_end == -1:
            _range = SourceRange.from_absolute_position(
                filename,
                AbsolutePosition(file, position))
            raise NoCloseError(annotation_start, _range)

        return (SourceRange.from_absolute_position(
                    filename,
                    AbsolutePosition(file, position),
                    AbsolutePosition(file, end_end)),
                end_end)
Example #23
0
    def test_escape_strings(self):
        text = [r"'I\'ll be back' -T1000"]
        uut = AnnotationBear(self.section1, Queue())
        test_range = SourceRange.from_absolute_position(
            'F',
            AbsolutePosition(text, 0),
            AbsolutePosition(text, text[0].find("'", 4)))
        with execute_bear(uut, 'F', text) as result:
            self.assertEqual(result[0].contents['strings'], (test_range,))

        text = ['''
            """"quoting inside quoting"
            """
            ''']
        uut = AnnotationBear(self.section1, Queue())
        with execute_bear(uut, 'F', text) as results:
            for result in results:
                # The """" was recognized as a string start and end before.
                # That lead to a Result being yielded because of unclosed
                # quotes, this asserts that no such thing happened.
                self.assertEqual(type(result), HiddenResult)
Example #24
0
    def find_with_start_end(filename, file, annot):
        """
        Gives all positions of annotations which have a start and end.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param annot:    A dict containing start of annotation as key and end of
                         annotation as value.
        :return:         A set of SourceRanges giving the range of annotation.
        """
        text = ''.join(file)
        found_pos = set()
        for annot_type in annot:
            found_pos.update(unescaped_search_in_between(
                                           annot_type, annot[annot_type], text))
        if found_pos:
            found_pos = set(SourceRange.from_absolute_position(
                                filename,
                                AbsolutePosition(file, position.begin.range[0]),
                                AbsolutePosition(
                                    file, position.end.range[1] - 1))
                            for position in found_pos)
        return found_pos
Example #25
0
    def find_with_start_end(filename, file, annot):
        """
        Gives all positions of annotations which have a start and end.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param annot:    A dict containing start of annotation as key and end of
                         annotation as value.
        :return:         A set of SourceRanges giving the range of annotation.
        """
        text = ''.join(file)
        found_pos = set()
        for annot_type in annot:
            found_pos.update(unescaped_search_in_between(
                                           annot_type, annot[annot_type], text))
        if found_pos:
            found_pos = set(SourceRange.from_absolute_position(
                                filename,
                                AbsolutePosition(file, position.begin.range[0]),
                                AbsolutePosition(
                                    file, position.end.range[1] - 1))
                            for position in found_pos)
        return found_pos
Example #26
0
    def find_singleline_comments(filename, file, comments):
        """
        Finds all single-line comments.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param comments: A list containing different types of
                         single-line comments.
        :return:         A set of SourceRange objects with start as the
                         beginning of the comment and end as
                         the termination of line.
        """
        text = ''.join(file)
        single_comments = set()
        for comment_type in comments:
            for found in unescaped_search_for(comment_type, text):
                start = found.start()
                end = text.find('\n', start)
                end = len(text) - 1 if end == -1 else end
                single_comments.add(SourceRange.from_absolute_position(
                                        filename,
                                        AbsolutePosition(file, start),
                                        AbsolutePosition(file, end)))
        return single_comments
Example #27
0
    def find_singleline_comments(filename, file, comments):
        """
        Finds all single-line comments.

        :param filename: Name of the file on which the bear is running.
        :param file:     Contents of the file in the form of tuple of lines.
        :param comments: A list containing different types of
                         single-line comments.
        :return:         A set of SourceRange objects with start as the
                         beginning of the comment and end as
                         the termination of line.
        """
        text = ''.join(file)
        single_comments = set()
        for comment_type in comments:
            for found in unescaped_search_for(comment_type, text):
                start = found.start()
                end = text.find('\n', start)
                end = len(text) - 1 if end == -1 else end
                single_comments.add(SourceRange.from_absolute_position(
                                        filename,
                                        AbsolutePosition(file, start),
                                        AbsolutePosition(file, end)))
        return single_comments