From 93113cfa0021725d6401ceb4f43b301bcf941da0 Mon Sep 17 00:00:00 2001 From: Andras Tim Date: Sun, 29 Oct 2017 04:32:29 +0100 Subject: [PATCH] checker: Added checkers for too more empty lines - fix: #4 --- docs/rules/WSC008.rst | 15 +++++++++ examples/WSC008_more_empty_lines.py | 18 +++++++++++ examples/multiple_problems.py | 3 ++ tests/performance/test_checker_performance.py | 15 +++++++++ tests/unit/checker/test_rules.py | 32 +++++++++++++++++++ wscheck/checker.py | 14 +++++++- 6 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 docs/rules/WSC008.rst create mode 100644 examples/WSC008_more_empty_lines.py diff --git a/docs/rules/WSC008.rst b/docs/rules/WSC008.rst new file mode 100644 index 0000000..2df43fb --- /dev/null +++ b/docs/rules/WSC008.rst @@ -0,0 +1,15 @@ +WSC008: More than 2 empty lines +================================ + +Alerting for more than 2 empty lines after the firs and before the last non-empty lines. + + +Example +------- + +.. test-wsc:: examples/WSC008_more_empty_lines.py + + In line 10: + os.makedirs(self.__print_cache_dir, exist_ok=True) + ^-- WSC008: More than 2 empty lines (+1) + diff --git a/examples/WSC008_more_empty_lines.py b/examples/WSC008_more_empty_lines.py new file mode 100644 index 0000000..ae0a63b --- /dev/null +++ b/examples/WSC008_more_empty_lines.py @@ -0,0 +1,18 @@ +class LabelPrinter: + def __generate_pdf(self): + pdf_generator = _LabelPdfGenerator() + pdf_generator.generate_label( + self.__title, self.__data, self.__logo_path, config.App.LABEL_BORDER, + output_path=self.__pdf_path) + + + def __prepare_print_cache_dir(self): + os.makedirs(self.__print_cache_dir, exist_ok=True) + + + + def __get_pdf_path(self) -> str: + pdf_name = self.__pdf_name_template.format( + data=self.__data, + title_hash=hashlib.sha1(self.__title.encode()).hexdigest()) + return os.path.join(self.__print_cache_dir, pdf_name) diff --git a/examples/multiple_problems.py b/examples/multiple_problems.py index 15cd161..797c830 100644 --- a/examples/multiple_problems.py +++ b/examples/multiple_problems.py @@ -12,9 +12,12 @@ def __generate_pdf(self): self.__title, self.__data, self.__logo_path, config.App.LABEL_BORDER, output_path=self.__pdf_path) + def __prepare_print_cache_dir(self): os.makedirs(self.__cache_dir, exist_ok=True) + + def __get_pdf_path(self) -> str: pdf_name = self.__pdf_name_template.format( data=self.__data, diff --git a/tests/performance/test_checker_performance.py b/tests/performance/test_checker_performance.py index 362803d..62ed75d 100644 --- a/tests/performance/test_checker_performance.py +++ b/tests/performance/test_checker_performance.py @@ -166,3 +166,18 @@ def test_wsc007(benchmark, text, expected_rules, expected_issue_count): File begins with newline """ _measure(benchmark, text, expected_rules, expected_issue_count) + + +@parametrize_with_names('text,expected_rules,expected_issue_count', { + 'head_empty-3': [_text(head=_line(suffix=DEFAULT_EOL * 3)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 + 'head_empty-21': [_text(head=_line(suffix=DEFAULT_EOL * 21)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 + 'center_empty-3': [_text(center=_line(suffix=DEFAULT_EOL * 3)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 + 'center_empty-21': [_text(center=_line(suffix=DEFAULT_EOL * 21)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 + 'foot_empty-3': [_text(foot=_line(prefix=DEFAULT_EOL * 3)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 + 'foot_empty-21': [_text(foot=_line(prefix=DEFAULT_EOL * 21)), ['WSC008'], CHECK_COUNT], # noqa: E241,E501 +}) +def test_wsc008(benchmark, text, expected_rules, expected_issue_count): + """ + More than 2 empty lines + """ + _measure(benchmark, text, expected_rules, expected_issue_count) diff --git a/tests/unit/checker/test_rules.py b/tests/unit/checker/test_rules.py index eaf2812..7f870bc 100644 --- a/tests/unit/checker/test_rules.py +++ b/tests/unit/checker/test_rules.py @@ -216,6 +216,38 @@ def test_non_spaces_in_indentation_is_bad(self, checker, content, col): ] == checker.issues +class TestEmptyLines(object): + """ + WSC008: More than 2 empty lines + """ + @pytest.mark.parametrize('text', [ + 'cherry\napple\n', + 'cherry\n\napple\n', + 'cherry\n\n\napple\n', + ]) + def test_valid_amount_of_empty_lines(self, checker, text): + checker.check_text(text) + assert [] == checker.issues + + def test_3_empty_lines(self, checker): + checker.check_text('cherry\n\n\n\napple\n') + assert [ + { + 'rule': 'WSC008', 'path': '', 'line': 1, 'col': 7, + 'context': '', 'message_suffix': '(+1)' + }, + ] == checker.issues + + def test_5_empty_lines(self, checker): + checker.check_text('cherry\n\n\n\n\n\napple\n') + assert [ + { + 'rule': 'WSC008', 'path': '', 'line': 1, 'col': 7, + 'context': '', 'message_suffix': '(+3)' + }, + ] == checker.issues + + class TestComplexCases(object): def test_multiple_issues(self, checker): checker.check_text('\n\n \tpineapple \rbanana') diff --git a/wscheck/checker.py b/wscheck/checker.py index 2de557d..f9091e4 100644 --- a/wscheck/checker.py +++ b/wscheck/checker.py @@ -8,6 +8,7 @@ 'WSC005': 'No newline at end of file', 'WSC006': 'Too many newline at end of file', 'WSC007': 'File begins with newline', + 'WSC008': 'More than 2 empty lines', } @@ -82,8 +83,11 @@ def _check_by_lines(self, source_path, lines): :type source_path: str :type lines: list """ + empty_lines = 0 + for line, line_text_eol in enumerate(lines, start=1): line_text, line_eol = line_text_eol + stripped_line_text = line_text.strip() if 'WSC001' in self._rules: if not line_eol == '' and not line_eol == '\n': @@ -96,9 +100,17 @@ def _check_by_lines(self, source_path, lines): self._add_issue(rule='WSC002', path=source_path, line=line, col=tailing_whitespace_match.start() + 1, context=line_text) - if line_text.strip() == '': + if stripped_line_text == '': + empty_lines += 1 continue + if 'WSC008' in self._rules: + if empty_lines > 2: + self._add_issue(rule='WSC008', path=source_path, line=line - empty_lines, col=1, + context=lines[line - empty_lines + 1][0], + message_suffix='(+{})'.format(empty_lines - 2)) + empty_lines = 0 + indent_match = self._LINE_INDENT_TEMPLATE.match(line_text) if indent_match is not None: line_indent = indent_match.group()