Example #1
0
    def run(self,
            filename,
            file,
            max_line_length: int = 79,
            indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH,
            ignore_length_regex: typed_list(str) = ()):
        '''
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length:     Maximum number of characters for a line,
                                    the newline character being excluded.
        :param indent_size:         Number of spaces per indentation level.
        :param ignore_length_regex: Lines matching each of the regular
                                    expressions in this list will be ignored.
        '''
        spacing_helper = SpacingHelper(indent_size)
        ignore_regexes = [re.compile(regex) for regex in ignore_length_regex]

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                if any(regex.search(line) for regex in ignore_regexes):
                    continue

                yield Result.from_values(
                    origin=self,
                    message="Line is longer than allowed." +
                    " ({actual} > {maximum})".format(actual=len(line) - 1,
                                                     maximum=max_line_length),
                    file=filename,
                    line=line_number + 1,
                    column=max_line_length + 1,
                    end_line=line_number + 1,
                    end_column=len(line))
    def test_print_spaces_tabs_in_unicode(self):
        printer = StringPrinter()

        sh = SpacingHelper(4)

        test_string = "\the\tllo world   "
        print_spaces_tabs_in_unicode(
            printer,
            test_string,
            dict(sh.yield_tab_lengths(test_string)),
            "red")
        self.assertEqual(printer.string, "--->he->llo•world•••")

        # Test the case when the bullet can't be printed because of encoding
        # problems.
        def hijack_print(text, *args, **kwargs):
            if "•" in text:
                raise UnicodeEncodeError("test-codec", "", 0, 1, "")
            else:
                return StringPrinter.print(printer, text, *args, **kwargs)

        printer.print = hijack_print

        printer.clear()
        test_string = " he\tllo  world "
        print_spaces_tabs_in_unicode(printer,
                                     test_string,
                                     dict(sh.yield_tab_lengths(test_string)),
                                     "red")
        self.assertEqual(printer.string, ".he>llo..world.")
Example #3
0
    def run(self,
            filename,
            file,
            max_line_length: int=80,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH):
        '''
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length: Maximum number of characters for a line.
        :param tab_width:       Number of spaces to show for one tab.
        '''
        spacing_helper = SpacingHelper(tab_width)

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                yield Result.from_values(
                    origin=self,
                    message="Line is longer than allowed." +
                            " ({actual} > {maximum})".format(
                                actual=len(line)-1,
                                maximum=max_line_length),
                    file=filename,
                    line=line_number + 1,
                    column=max_line_length + 1,
                    end_line=line_number + 1,
                    end_column=len(line))
Example #4
0
    def run(self,
            filename,
            file,
            max_line_length: int=79,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH,
            ignore_length_regex: typed_list(str)=()):
        '''
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length:     Maximum number of characters for a line,
                                    the newline character being excluded.
        :param tab_width:           Number of spaces to show for one tab.
        :param ignore_length_regex: Lines matching each of the regular
                                    expressions in this list will be ignored.
        '''
        spacing_helper = SpacingHelper(tab_width)
        ignore_regexes = [re.compile(regex) for regex in ignore_length_regex]

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                if any(regex.search(line) for regex in ignore_regexes):
                    continue

                yield Result.from_values(
                    origin=self,
                    message="Line is longer than allowed." +
                            " ({actual} > {maximum})".format(
                                actual=len(line)-1,
                                maximum=max_line_length),
                    file=filename,
                    line=line_number + 1,
                    column=max_line_length + 1,
                    end_line=line_number + 1,
                    end_column=len(line))
    def test_print_spaces_tabs_in_unicode(self):
        printer = StringPrinter()

        sh = SpacingHelper(4)

        test_string = "\the\tllo world   "
        print_spaces_tabs_in_unicode(printer, test_string,
                                     dict(sh.yield_tab_lengths(test_string)),
                                     "red")
        self.assertEqual(printer.string, "--->he->llo•world•••")

        # Test the case when the bullet can't be printed because of encoding
        # problems.
        def hijack_print(text, *args, **kwargs):
            if "•" in text:
                raise UnicodeEncodeError("test-codec", "", 0, 1, "")
            else:
                return StringPrinter.print(printer, text, *args, **kwargs)

        printer.print = hijack_print

        printer.clear()
        test_string = " he\tllo  world "
        print_spaces_tabs_in_unicode(printer, test_string,
                                     dict(sh.yield_tab_lengths(test_string)),
                                     "red")
        self.assertEqual(printer.string, ".he>llo..world.")
Example #6
0
    def run(self,
            filename,
            file,
            max_line_length: int=80,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH,
            ignore_length_regex: str=''):
        '''
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length:     Maximum number of characters for a line.
        :param tab_width:           Number of spaces to show for one tab.
        :param ignore_length_regex: All lines matching this regular expression
                                    will be ignored.
        '''
        spacing_helper = SpacingHelper(tab_width)
        ignore_regex = re.compile(ignore_length_regex)

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                if ignore_length_regex and ignore_regex.match(line):
                    continue

                yield Result.from_values(
                    origin=self,
                    message="Line is longer than allowed." +
                            " ({actual} > {maximum})".format(
                                actual=len(line)-1,
                                maximum=max_line_length),
                    file=filename,
                    line=line_number + 1,
                    column=max_line_length + 1,
                    end_line=line_number + 1,
                    end_column=len(line))
Example #7
0
    def run(self,
            filename,
            file,
            max_line_length: int=80,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH):
        '''
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length: Maximum number of characters for a line.
        :param tab_width:       Number of spaces to show for one tab.
        '''
        spacing_helper = SpacingHelper(tab_width)

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                yield Result.from_values(
                    origin=self,
                    message="Line is longer than allowed." +
                            " ({actual} > {maximum})".format(
                                actual=len(line)-1,
                                maximum=max_line_length),
                    file=filename,
                    line=line_number + 1,
                    column=max_line_length + 1,
                    end_line=line_number + 1,
                    end_column=len(line))
Example #8
0
    def run_bear(self,
                 filename,
                 file,
                 max_line_length: int,
                 tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH):
        """
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length: Maximum number of characters for a line.
        :param tab_width: Number of spaces to show for one tab.
        """
        results = []
        bearname = self.__class__.__name__
        spacing_helper = SpacingHelper.from_section(section=self.section)

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                results.append(
                    Result(origin=bearname,
                           message=_("Line is longer than allowed.") +
                           " ({actual} > {maximum})".format(
                               actual=len(line), maximum=max_line_length),
                           file=filename,
                           line_nr=line_number + 1))

        return results
Example #9
0
    def run(self,
            filename,
            file,
            max_line_length: int,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH):
        """
        Yields results for all lines longer than the given maximum line length.

        :param max_line_length: Maximum number of characters for a line.
        :param tab_width: Number of spaces to show for one tab.
        """
        results = []
        spacing_helper = SpacingHelper.from_section(section=self.section)

        for line_number, line in enumerate(file):
            line = spacing_helper.replace_tabs_with_spaces(line)
            if len(line) > max_line_length + 1:
                results.append(
                    Result(origin=self,
                           message=_("Line is longer than allowed.") +
                                   " ({actual} > {maximum})".format(
                                       actual=len(line),
                                       maximum=max_line_length),
                           file=filename,
                           line_nr=line_number + 1))

        return results
Example #10
0
def print_lines(console_printer,
                file_dict,
                section,
                sourcerange):
    """
    Prints the lines between the current and the result line. If needed
    they will be shortened.

    :param console_printer: Object to print messages on the console.
    :param file_dict:       A dictionary containing all files as values with
                            filenames as key.
    :param sourcerange:     The SourceRange object referring to the related
                            lines to print.
    """
    for i in range(sourcerange.start.line, sourcerange.end.line + 1):
        console_printer.print(format_lines(lines='', line_nr=i),
                              color=FILE_LINES_COLOR,
                              end='')
        line = file_dict[sourcerange.file][i - 1].rstrip("\n")
        tab_width = int(section.get('tab_width', 4))
        s = SpacingHelper(tab_width)
        tab_dict = dict(s.yield_tab_lengths(line))
        printed_chars = 0
        if i == sourcerange.start.line and sourcerange.start.column:
            print_spaces_tabs_in_unicode(
                console_printer, line[:sourcerange.start.column-1],
                tab_dict, FILE_LINES_COLOR)

            printed_chars = sourcerange.start.column-1

        if i == sourcerange.end.line and sourcerange.end.column:
            print_spaces_tabs_in_unicode(
                console_printer, line[printed_chars:sourcerange.end.column-1],
                tab_dict, HIGHLIGHTED_CODE_COLOR, printed_chars)

            print_spaces_tabs_in_unicode(
                console_printer, line[sourcerange.end.column-1:],
                tab_dict, FILE_LINES_COLOR, sourcerange.end.column-1)
            console_printer.print("")
        else:
            print_spaces_tabs_in_unicode(
                console_printer, line[printed_chars:], tab_dict,
                HIGHLIGHTED_CODE_COLOR, printed_chars)
            console_printer.print("")
Example #11
0
def print_lines(console_printer,
                file_dict,
                section,
                sourcerange):
    """
    Prints the lines between the current and the result line. If needed
    they will be shortened.

    :param console_printer: Object to print messages on the console.
    :param file_dict:       A dictionary containing all files as values with
                            filenames as key.
    :param sourcerange:     The SourceRange object referring to the related
                            lines to print.
    """
    for i in range(sourcerange.start.line, sourcerange.end.line + 1):
        console_printer.print(format_lines(lines='', line_nr=i),
                              color=FILE_LINES_COLOR,
                              end='')
        line = file_dict[sourcerange.file][i - 1].rstrip("\n")
        tab_width = int(section.get('tab_width', 4))
        s = SpacingHelper(tab_width)
        tab_dict = dict(s.yield_tab_lengths(line))
        printed_chars = 0
        if i == sourcerange.start.line and sourcerange.start.column:
            print_spaces_tabs_in_unicode(
                console_printer, line[:sourcerange.start.column-1],
                tab_dict, FILE_LINES_COLOR)

            printed_chars = sourcerange.start.column-1

        if i == sourcerange.end.line and sourcerange.end.column:
            print_spaces_tabs_in_unicode(
                console_printer, line[printed_chars:sourcerange.end.column-1],
                tab_dict, HIGHLIGHTED_CODE_COLOR, printed_chars)

            print_spaces_tabs_in_unicode(
                console_printer, line[sourcerange.end.column-1:],
                tab_dict, FILE_LINES_COLOR, sourcerange.end.column)
            console_printer.print("")
        else:
            print_spaces_tabs_in_unicode(
                console_printer, line[printed_chars:], tab_dict,
                HIGHLIGHTED_CODE_COLOR, printed_chars)
            console_printer.print("")
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool=False,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH):
        """
        Checks the space consistency for each line.

        :param use_spaces:                True if spaces are to be used
                                          instead of tabs.
        :param allow_trailing_whitespace: Whether to allow trailing whitespace
                                          or not.
        :param tab_width:                 Number of spaces representing one
                                          tab.
        """
        results = []

        spacing_helper = SpacingHelper(tab_width)

        for line_number, line in enumerate(file):
            replacement = line

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(" \t\n") + "\n"

            if use_spaces:
                replacement = spacing_helper.replace_tabs_with_spaces(
                    replacement)
            else:
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)

            if replacement != line:
                diff = Diff()
                diff.change_line(line_number + 1, line, replacement)
                results.append(PatchResult(self,
                                           _("Line contains spacing "
                                             "inconsistencies."),
                                           {filename: diff},
                                           filename,
                                           line_nr=line_number+1))

        return results
Example #13
0
class SpacingHelperTestCase(unittest.TestCase):
    def setUp(self):
        self.uut = SpacingHelper()

    def test_needed_settings(self):
        self.assertEqual(list(self.uut.get_optional_settings()), ["tab_width"])
        self.assertEqual(list(self.uut.get_non_optional_settings()), [])

    def test_construction(self):
        section = Section("test section")
        self.assertRaises(TypeError, SpacingHelper, "no integer")
        self.assertRaises(TypeError, self.uut.from_section, 5)

        self.assertEqual(self.uut.tab_width,
                         self.uut.from_section(section).tab_width)

        section.append(Setting("tab_width", "invalid"))
        # Setting won't be converted since it's not possible, SpacingHelper
        # will then complain with TypeError
        self.assertRaises(TypeError, self.uut.from_section, section)

        # This is assumed in some tests. If you want to change this value, be
        # sure to change the tests too
        self.assertEqual(self.uut.DEFAULT_TAB_WIDTH, 4)
        self.assertEqual(self.uut.tab_width, self.uut.DEFAULT_TAB_WIDTH)

    def test_get_indentation(self):
        self.assertRaises(TypeError, self.uut.get_indentation, 5)

        self.assertEqual(self.uut.get_indentation("no indentation"), 0)
        self.assertEqual(self.uut.get_indentation(" indentation"), 1)
        self.assertEqual(self.uut.get_indentation("  indentation"), 2)
        self.assertEqual(self.uut.get_indentation("\tindentation"),
                         self.uut.DEFAULT_TAB_WIDTH)

        # Having a space before the tab shouldn't make any difference
        self.assertEqual(self.uut.get_indentation(" \tindentation"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t indentation"),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation("\t indentation"),
                         self.uut.DEFAULT_TAB_WIDTH + 1)

        # same tests but with indentation only
        self.assertEqual(self.uut.get_indentation("\t"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t "),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation("\t "),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation("\t\t"),
                         self.uut.DEFAULT_TAB_WIDTH * 2)

    def test_replace_tabs_with_spaces(self):
        self.assertRaises(TypeError, self.uut.replace_tabs_with_spaces, 5)

        self.assertEqual(self.uut.replace_tabs_with_spaces(""), "")
        self.assertEqual(self.uut.replace_tabs_with_spaces(" "), " ")
        self.assertEqual(self.uut.replace_tabs_with_spaces("\t"),
                         " " * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("\t\t"),
                         " " * self.uut.DEFAULT_TAB_WIDTH * 2)
        self.assertEqual(self.uut.replace_tabs_with_spaces(" \t"),
                         " " * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("  \t"),
                         " " * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("d \t "),
                         "d" + " " * self.uut.DEFAULT_TAB_WIDTH)

    def test_replace_spaces_with_tabs(self):
        self.assertRaises(TypeError, self.uut.replace_spaces_with_tabs, 5)

        self.assertEqual(self.uut.replace_spaces_with_tabs(""), "")
        self.assertEqual(self.uut.replace_spaces_with_tabs(" "), " ")
        self.assertEqual(self.uut.replace_spaces_with_tabs("    "), "\t")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   \t"), "\t")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd  "),
                         "   dd  ")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd d "),
                         "   dd d ")  # One space shouldnt be replaced
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd   "),
                         "   dd\t")
        self.assertEqual(
            self.uut.replace_spaces_with_tabs(" \t   a_text   another"),
            "\t   a_text\tanother")
        self.assertEqual(self.uut.replace_spaces_with_tabs("d  d"), "d  d")
Example #14
0
 def setUp(self):
     self.uut = SpacingHelper()
Example #15
0
class SpacingHelperTest(unittest.TestCase):

    def setUp(self):
        self.uut = SpacingHelper()

    def test_needed_settings(self):
        self.assertEqual(list(self.uut.get_optional_settings()), ['tab_width'])
        self.assertEqual(list(self.uut.get_non_optional_settings()), [])

    def test_construction(self):
        section = Section('test section')
        self.assertRaises(TypeError, SpacingHelper, 'no integer')
        self.assertRaises(TypeError, self.uut.from_section, 5)

        self.assertEqual(self.uut.tab_width,
                         self.uut.from_section(section).tab_width)

        # This is assumed in some tests. If you want to change this value, be
        # sure to change the tests too
        self.assertEqual(self.uut.DEFAULT_TAB_WIDTH, 4)
        self.assertEqual(self.uut.tab_width, self.uut.DEFAULT_TAB_WIDTH)

    def test_get_indentation(self):
        self.assertRaises(TypeError, self.uut.get_indentation, 5)

        self.assertEqual(self.uut.get_indentation('no indentation'), 0)
        self.assertEqual(self.uut.get_indentation(' indentation'), 1)
        self.assertEqual(self.uut.get_indentation('  indentation'), 2)
        self.assertEqual(self.uut.get_indentation('\tindentation'),
                         self.uut.DEFAULT_TAB_WIDTH)

        # Having a space before the tab shouldn't make any difference
        self.assertEqual(self.uut.get_indentation(' \tindentation'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t indentation'),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation('\t indentation'),
                         self.uut.DEFAULT_TAB_WIDTH+1)

        # same tests but with indentation only
        self.assertEqual(self.uut.get_indentation('\t'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t '),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation('\t '),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation('\t\t'),
                         self.uut.DEFAULT_TAB_WIDTH*2)

    def test_replace_tabs_with_spaces(self):
        self.assertRaises(TypeError, self.uut.replace_tabs_with_spaces, 5)

        self.assertEqual(self.uut.replace_tabs_with_spaces(''), '')
        self.assertEqual(self.uut.replace_tabs_with_spaces(' '), ' ')
        self.assertEqual(self.uut.replace_tabs_with_spaces('\t'),
                         ' '*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('\t\t'),
                         ' '*self.uut.DEFAULT_TAB_WIDTH*2)
        self.assertEqual(self.uut.replace_tabs_with_spaces(' \t'),
                         ' '*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('  \t'),
                         ' '*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('d \t '),
                         'd' + ' '*self.uut.DEFAULT_TAB_WIDTH)

    def test_replace_spaces_with_tabs(self):
        self.assertRaises(TypeError, self.uut.replace_spaces_with_tabs, 5)

        self.assertEqual(self.uut.replace_spaces_with_tabs(''), '')
        self.assertEqual(self.uut.replace_spaces_with_tabs(' '), ' ')
        self.assertEqual(self.uut.replace_spaces_with_tabs('    '), '\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   \t'), '\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd  '),
                         '   dd  ')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd d '),
                         '   dd d ')  # One space shouldnt be replaced
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd   '),
                         '   dd\t')
        self.assertEqual(
            self.uut.replace_spaces_with_tabs(' \t   a_text   another'),
            '\t   a_text\tanother')
        self.assertEqual(self.uut.replace_spaces_with_tabs('123\t'), '123\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('d  d'), 'd  d')
Example #16
0
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool = False,
            tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH,
            enforce_newline_at_EOF: bool = True):
        '''
        Checks the space consistency for each line.

        :param use_spaces:                True if spaces are to be used instead
                                          of tabs.
        :param allow_trailing_whitespace: Whether to allow trailing whitespace
                                          or not.
        :param tab_width:                 Number of spaces representing one
                                          tab.
        :param enforce_newline_at_EOF:    Whether to enforce a newline at the
                                          End Of File.
        '''
        spacing_helper = SpacingHelper(tab_width)
        result_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != "\n":
                    replacement += "\n"
                    result_texts.append("No newline at EOF.")

            if not allow_trailing_whitespace:
                pre_replacement = line
                replacement = replacement.rstrip(" \t\n") + "\n"
                if replacement != pre_replacement:
                    result_texts.append("Trailing whitespaces.")

            if use_spaces:
                pre_replacement = replacement
                replacement = spacing_helper.replace_tabs_with_spaces(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Tabs used instead of spaces.")
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Spaces used instead of tabs.")

            if len(result_texts) > 0:
                diff = Diff(file)
                diff.change_line(line_number, line, replacement)
                inconsistencies = "".join("\n- " + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    "Line contains following spacing inconsistencies:" +
                    inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number)
                result_texts = []
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool = False,
            tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH,
            enforce_newline_at_EOF: bool = True):
        '''
        Check and correct spacing for all textual data. This includes usage of
        tabs vs. spaces, trailing whitespace and (missing) newlines before
        the end of the file.

        :param use_spaces:                True if spaces are to be used instead
                                          of tabs.
        :param allow_trailing_whitespace: Whether to allow trailing whitespace
                                          or not.
        :param tab_width:                 Number of spaces representing one
                                          tab.
        :param enforce_newline_at_EOF:    Whether to enforce a newline at the
                                          End Of File.
        '''
        spacing_helper = SpacingHelper(tab_width)
        result_texts = []
        additional_info_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != "\n":
                    replacement += "\n"
                    result_texts.append("No newline at EOF.")
                    additional_info_texts.append(
                        "A trailing newline character ('\\n') is missing from "
                        "your file. "
                        "<http://stackoverflow.com/a/5813359/3212182> gives "
                        "more information about why you might need one.")

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(" \t\n") + "\n"
                if replacement != line.rstrip("\n") + "\n":
                    result_texts.append("Trailing whitespaces.")
                    additional_info_texts.append(
                        "Your source code contains trailing whitespaces. Those "
                        "usually have no meaning. Please consider removing "
                        "them.")

            if use_spaces:
                pre_replacement = replacement
                replacement = spacing_helper.replace_tabs_with_spaces(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Tabs used instead of spaces.")
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Spaces used instead of tabs.")

            if len(result_texts) > 0:
                diff = Diff(file)
                diff.change_line(line_number, line, replacement)
                inconsistencies = "".join("\n- " + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    "Line contains following spacing inconsistencies:" +
                    inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number,
                    additional_info="\n\n".join(additional_info_texts))
                result_texts = []
                additional_info_texts = []
Example #18
0
class SpacingHelperTest(unittest.TestCase):
    def setUp(self):
        self.uut = SpacingHelper()

    def test_needed_settings(self):
        self.assertEqual(list(self.uut.get_optional_settings()), ["tab_width"])
        self.assertEqual(list(self.uut.get_non_optional_settings()), [])

    def test_construction(self):
        section = Section("test section")
        self.assertRaises(TypeError, SpacingHelper, "no integer")
        self.assertRaises(TypeError, self.uut.from_section, 5)

        self.assertEqual(self.uut.tab_width,
                         self.uut.from_section(section).tab_width)

        section.append(Setting("tab_width", "invalid"))
        # Setting won't be converted since it's not possible, SpacingHelper
        # will then complain with TypeError
        self.assertRaises(TypeError, self.uut.from_section, section)

        # This is assumed in some tests. If you want to change this value, be
        # sure to change the tests too
        self.assertEqual(self.uut.DEFAULT_TAB_WIDTH, 4)
        self.assertEqual(self.uut.tab_width, self.uut.DEFAULT_TAB_WIDTH)

    def test_get_indentation(self):
        self.assertRaises(TypeError, self.uut.get_indentation, 5)

        self.assertEqual(self.uut.get_indentation("no indentation"), 0)
        self.assertEqual(self.uut.get_indentation(" indentation"), 1)
        self.assertEqual(self.uut.get_indentation("  indentation"), 2)
        self.assertEqual(self.uut.get_indentation("\tindentation"),
                         self.uut.DEFAULT_TAB_WIDTH)

        # Having a space before the tab shouldn't make any difference
        self.assertEqual(self.uut.get_indentation(" \tindentation"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t indentation"),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation("\t indentation"),
                         self.uut.DEFAULT_TAB_WIDTH+1)

        # same tests but with indentation only
        self.assertEqual(self.uut.get_indentation("\t"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t"),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(" \t "),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation("\t "),
                         self.uut.DEFAULT_TAB_WIDTH+1)
        self.assertEqual(self.uut.get_indentation("\t\t"),
                         self.uut.DEFAULT_TAB_WIDTH*2)

    def test_replace_tabs_with_spaces(self):
        self.assertRaises(TypeError, self.uut.replace_tabs_with_spaces, 5)

        self.assertEqual(self.uut.replace_tabs_with_spaces(""), "")
        self.assertEqual(self.uut.replace_tabs_with_spaces(" "), " ")
        self.assertEqual(self.uut.replace_tabs_with_spaces("\t"),
                         " "*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("\t\t"),
                         " "*self.uut.DEFAULT_TAB_WIDTH*2)
        self.assertEqual(self.uut.replace_tabs_with_spaces(" \t"),
                         " "*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("  \t"),
                         " "*self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces("d \t "),
                         "d" + " "*self.uut.DEFAULT_TAB_WIDTH)

    def test_replace_spaces_with_tabs(self):
        self.assertRaises(TypeError, self.uut.replace_spaces_with_tabs, 5)

        self.assertEqual(self.uut.replace_spaces_with_tabs(""), "")
        self.assertEqual(self.uut.replace_spaces_with_tabs(" "), " ")
        self.assertEqual(self.uut.replace_spaces_with_tabs("    "), "\t")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   \t"), "\t")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd  "),
                         "   dd  ")
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd d "),
                         "   dd d ")  # One space shouldnt be replaced
        self.assertEqual(self.uut.replace_spaces_with_tabs("   dd   "),
                         "   dd\t")
        self.assertEqual(
            self.uut.replace_spaces_with_tabs(" \t   a_text   another"),
            "\t   a_text\tanother")
        self.assertEqual(self.uut.replace_spaces_with_tabs("d  d"), "d  d")
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool = False,
            indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH,
            enforce_newline_at_EOF: bool = True,
            ):
        '''
        Check and correct spacing for all textual data. This includes usage of
        tabs vs. spaces, trailing whitespace and (missing) newlines before
        the end of the file.

        :param use_spaces:
            True if spaces are to be used instead of tabs.
        :param allow_trailing_whitespace:
            Whether to allow trailing whitespace or not.
        :param indent_size:
            Number of spaces per indentation level.
        :param enforce_newline_at_EOF:
            Whether to enforce a newline at the End Of File.
        '''
        spacing_helper = SpacingHelper(indent_size)
        result_texts = []
        additional_info_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != '\n':
                    replacement += '\n'
                    result_texts.append('No newline at EOF.')
                    additional_info_texts.append(
                        "A trailing newline character ('\\n') is missing from "
                        'your file. '
                        '<http://stackoverflow.com/a/5813359/3212182> gives '
                        'more information about why you might need one.')

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(' \t\n') + '\n'
                if replacement != line.rstrip('\n') + '\n':
                    result_texts.append('Trailing whitespaces.')
                    additional_info_texts.append(
                        'Your source code contains trailing whitespaces. '
                        'Those usually have no meaning. Please consider '
                        'removing them.')

            if use_spaces:
                pre_replacement = replacement
                replacement = replacement.expandtabs(indent_size)
                if replacement != pre_replacement:
                    result_texts.append('Tabs used instead of spaces.')
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append('Spaces used instead of tabs.')

            if len(result_texts) > 0:
                diff = Diff(file)
                diff.change_line(line_number, line, replacement)
                inconsistencies = ''.join('\n- ' + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    'Line contains following spacing inconsistencies:'
                    + inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number,
                    additional_info='\n\n'.join(additional_info_texts))
                result_texts = []
                additional_info_texts = []
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool=False,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH,
            enforce_newline_at_EOF: bool=True):
        '''
        Check and correct spacing for all textual data. This includes usage of
        tabs vs. spaces, trailing whitespace and (missing) newlines before
        the end of the file.

        :param use_spaces:                True if spaces are to be used instead
                                          of tabs.
        :param allow_trailing_whitespace: Whether to allow trailing whitespace
                                          or not.
        :param tab_width:                 Number of spaces representing one
                                          tab.
        :param enforce_newline_at_EOF:    Whether to enforce a newline at the
                                          End Of File.
        '''
        spacing_helper = SpacingHelper(tab_width)
        result_texts = []
        additional_info_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != "\n":
                    replacement += "\n"
                    result_texts.append("No newline at EOF.")
                    additional_info_texts.append(
                        "A trailing newline character ('\\n') is missing from "
                        "your file. "
                        "<http://stackoverflow.com/a/5813359/3212182> gives "
                        "more information about why you might need one.")

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(" \t\n") + "\n"
                if replacement != line.rstrip("\n") + "\n":
                    result_texts.append("Trailing whitespaces.")
                    additional_info_texts.append(
                        "Your source code contains trailing whitespaces. Those "
                        "usually have no meaning. Please consider removing "
                        "them.")

            if use_spaces:
                pre_replacement = replacement
                replacement = spacing_helper.replace_tabs_with_spaces(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Tabs used instead of spaces.")
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append("Spaces used instead of tabs.")

            if len(result_texts) > 0:
                diff = Diff(file)
                diff.change_line(line_number, line, replacement)
                inconsistencies = "".join("\n- " + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    "Line contains following spacing inconsistencies:"
                    + inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number,
                    additional_info="\n\n".join(additional_info_texts))
                result_texts = []
                additional_info_texts = []
Example #21
0
class SpacingHelperTest(unittest.TestCase):
    def setUp(self):
        self.uut = SpacingHelper()

    def test_needed_settings(self):
        self.assertEqual(list(self.uut.get_optional_settings()), ['tab_width'])
        self.assertEqual(list(self.uut.get_non_optional_settings()), [])

    def test_construction(self):
        section = Section('test section')
        self.assertRaises(TypeError, SpacingHelper, 'no integer')
        self.assertRaises(TypeError, self.uut.from_section, 5)

        self.assertEqual(self.uut.tab_width,
                         self.uut.from_section(section).tab_width)

        # This is assumed in some tests. If you want to change this value, be
        # sure to change the tests too
        self.assertEqual(self.uut.DEFAULT_TAB_WIDTH, 4)
        self.assertEqual(self.uut.tab_width, self.uut.DEFAULT_TAB_WIDTH)

    def test_get_indentation(self):
        self.assertRaises(TypeError, self.uut.get_indentation, 5)

        self.assertEqual(self.uut.get_indentation('no indentation'), 0)
        self.assertEqual(self.uut.get_indentation(' indentation'), 1)
        self.assertEqual(self.uut.get_indentation('  indentation'), 2)
        self.assertEqual(self.uut.get_indentation('\tindentation'),
                         self.uut.DEFAULT_TAB_WIDTH)

        # Having a space before the tab shouldn't make any difference
        self.assertEqual(self.uut.get_indentation(' \tindentation'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t indentation'),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation('\t indentation'),
                         self.uut.DEFAULT_TAB_WIDTH + 1)

        # same tests but with indentation only
        self.assertEqual(self.uut.get_indentation('\t'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t'),
                         self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.get_indentation(' \t '),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation('\t '),
                         self.uut.DEFAULT_TAB_WIDTH + 1)
        self.assertEqual(self.uut.get_indentation('\t\t'),
                         self.uut.DEFAULT_TAB_WIDTH * 2)

    def test_replace_tabs_with_spaces(self):
        self.assertRaises(TypeError, self.uut.replace_tabs_with_spaces, 5)

        self.assertEqual(self.uut.replace_tabs_with_spaces(''), '')
        self.assertEqual(self.uut.replace_tabs_with_spaces(' '), ' ')
        self.assertEqual(self.uut.replace_tabs_with_spaces('\t'),
                         ' ' * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('\t\t'),
                         ' ' * self.uut.DEFAULT_TAB_WIDTH * 2)
        self.assertEqual(self.uut.replace_tabs_with_spaces(' \t'),
                         ' ' * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('  \t'),
                         ' ' * self.uut.DEFAULT_TAB_WIDTH)
        self.assertEqual(self.uut.replace_tabs_with_spaces('d \t '),
                         'd' + ' ' * self.uut.DEFAULT_TAB_WIDTH)

    def test_replace_spaces_with_tabs(self):
        self.assertRaises(TypeError, self.uut.replace_spaces_with_tabs, 5)

        self.assertEqual(self.uut.replace_spaces_with_tabs(''), '')
        self.assertEqual(self.uut.replace_spaces_with_tabs(' '), ' ')
        self.assertEqual(self.uut.replace_spaces_with_tabs('    '), '\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   \t'), '\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd  '),
                         '   dd  ')
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd d '),
                         '   dd d ')  # One space shouldnt be replaced
        self.assertEqual(self.uut.replace_spaces_with_tabs('   dd   '),
                         '   dd\t')
        self.assertEqual(
            self.uut.replace_spaces_with_tabs(' \t   a_text   another'),
            '\t   a_text\tanother')
        self.assertEqual(self.uut.replace_spaces_with_tabs('123\t'), '123\t')
        self.assertEqual(self.uut.replace_spaces_with_tabs('d  d'), 'd  d')
Example #22
0
 def setUp(self):
     self.uut = SpacingHelper()
    def run(
        self,
        filename,
        file,
        use_spaces: bool,
        allow_trailing_whitespace: bool = False,
        indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH,
        enforce_newline_at_EOF: bool = True,
    ):
        '''
        Check and correct spacing for all textual data. This includes usage of
        tabs vs. spaces, trailing whitespace and (missing) newlines before
        the end of the file.

        :param use_spaces:
            True if spaces are to be used instead of tabs.
        :param allow_trailing_whitespace:
            Whether to allow trailing whitespace or not.
        :param indent_size:
            Number of spaces per indentation level.
        :param enforce_newline_at_EOF:
            Whether to enforce a newline at the End Of File.
        '''
        spacing_helper = SpacingHelper(indent_size)
        result_texts = []
        additional_info_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != '\n':
                    replacement += '\n'
                    result_texts.append('No newline at EOF.')
                    additional_info_texts.append(
                        "A trailing newline character ('\\n') is missing from "
                        'your file. '
                        '<http://stackoverflow.com/a/5813359/3212182> gives '
                        'more information about why you might need one.')

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(' \t\n') + '\n'
                if replacement != line.rstrip('\n') + '\n':
                    result_texts.append('Trailing whitespaces.')
                    additional_info_texts.append(
                        'Your source code contains trailing whitespaces. '
                        'Those usually have no meaning. Please consider '
                        'removing them.')

            if use_spaces:
                pre_replacement = replacement
                replacement = replacement.expandtabs(indent_size)
                if replacement != pre_replacement:
                    result_texts.append('Tabs used instead of spaces.')
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append('Spaces used instead of tabs.')

            if len(result_texts) > 0:
                diff = Diff(file)
                diff.change_line(line_number, line, replacement)
                inconsistencies = ''.join('\n- ' + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    'Line contains following spacing inconsistencies:' +
                    inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number,
                    additional_info='\n\n'.join(additional_info_texts))
                result_texts = []
                additional_info_texts = []
Example #24
0
    def run(self,
            filename,
            file,
            use_spaces: bool,
            allow_trailing_whitespace: bool=False,
            tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH,
            enforce_newline_at_EOF: bool=True):
        '''
        Checks the space consistency for each line.

        :param use_spaces:                True if spaces are to be used instead
                                          of tabs.
        :param allow_trailing_whitespace: Whether to allow trailing whitespace
                                          or not.
        :param tab_width:                 Number of spaces representing one
                                          tab.
        :param enforce_newline_at_EOF:    Whether to enforce a newline at the
                                          End Of File.
        '''
        spacing_helper = SpacingHelper(tab_width)
        result_texts = []

        for line_number, line in enumerate(file, start=1):
            replacement = line

            if enforce_newline_at_EOF:
                # Since every line contains at the end at least one \n, only
                # the last line could potentially not have one. So we don't
                # need to check whether the current line_number is the last
                # one.
                if replacement[-1] != "\n":
                    replacement += "\n"
                    result_texts.append(_("No newline at EOF."))

            if not allow_trailing_whitespace:
                pre_replacement = line
                replacement = replacement.rstrip(" \t\n") + "\n"
                if replacement != pre_replacement:
                    result_texts.append(_("Trailing whitespaces."))

            if use_spaces:
                pre_replacement = replacement
                replacement = spacing_helper.replace_tabs_with_spaces(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append(_("Tabs used instead of spaces."))
            else:
                pre_replacement = replacement
                replacement = spacing_helper.replace_spaces_with_tabs(
                    replacement)
                if replacement != pre_replacement:
                    result_texts.append(_("Spaces used instead of tabs."))

            if len(result_texts) > 0:
                diff = Diff()
                diff.change_line(line_number, line, replacement)
                inconsistencies = "".join("\n- " + string
                                          for string in result_texts)
                yield Result.from_values(
                    self,
                    _("Line contains following spacing inconsistencies:")
                    + inconsistencies,
                    diffs={filename: diff},
                    file=filename,
                    line=line_number)
                result_texts = []