diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b725ea4..be1a27f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: with: python-version: "3.10" - name: Install tox - run: python -m pip install tox + run: python -m pip install tox tox-gh-actions - uses: actions/checkout@v3 with: fetch-depth: 0 @@ -39,35 +39,21 @@ jobs: run: tox -vv --notest - name: Run tests with tox run: tox -e py --skip-pkg-install - - name: Upload coverage data - uses: actions/upload-artifact@v3 + - name: Create Coveralls coverage report + uses: miurahr/coveralls-python-action@patch-pyprject-toml with: - name: coverage-data - path: ".tox/.coverage.*" + base-path: .tox + debug: true + parallel: true upload_coveralls: name: Upload Results to Coveralls needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install tox - run: python -m pip install tox - - name: Setup coverage - run: tox -e coverage --notest - - name: Download coverage data - uses: actions/download-artifact@v3 - with: - name: coverage-data - path: .tox - - name: Combine coverage reports - run: tox -e coverage - name: Upload coverage report to Coveralls uses: miurahr/coveralls-python-action@patch-pyprject-toml with: base-path: .tox + debug: true + parallel-finished: true diff --git a/docformatter.py b/docformatter.py index 2c07300..c7c93ff 100755 --- a/docformatter.py +++ b/docformatter.py @@ -553,7 +553,6 @@ def _format_code( modified_tokens = [] sio = io.StringIO(source) - previous_token_string = "" previous_token_type = None only_comments_so_far = True @@ -570,6 +569,7 @@ def _format_code( and token_string.startswith(self.QUOTE_TYPES) and ( previous_token_type == tokenize.INDENT + or previous_token_type == tokenize.NEWLINE or only_comments_so_far ) and is_in_range(self.args.line_range, start[0], end[0]) @@ -577,9 +577,7 @@ def _format_code( self.args.length_range, start[0], end[0] ) ): - indentation = ( - "" if only_comments_so_far else previous_token_string - ) + indentation = " " * (len(line) - len(line.lstrip())) token_string = self._do_format_docstring( indentation, token_string, @@ -592,7 +590,6 @@ def _format_code( ]: only_comments_so_far = False - previous_token_string = token_string previous_token_type = token_type # If the current token is a newline, the previous token was a @@ -1139,13 +1136,15 @@ def normalize_summary(summary): # remove trailing whitespace summary = summary.rstrip() - # Add period at end of sentence + # Add period at end of sentence and capitalize the first word of the + # summary. if ( summary and (summary[-1].isalnum() or summary[-1] in ['"', "'"]) and (not summary.startswith("#")) ): summary += "." + summary = summary[0].upper() + summary[1:] return summary diff --git a/pyproject.toml b/pyproject.toml index 072372f..86ce657 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -184,6 +184,15 @@ isolated_build = true skip_missing_interpreters = true skipsdist = true +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: py310 + pypy-3.6: pypy3 + [testenv] description = run the test suite using pytest under {basepython} deps = diff --git a/tests/test_format_code.py b/tests/test_format_code.py index 521303d..452219c 100644 --- a/tests/test_format_code.py +++ b/tests/test_format_code.py @@ -841,6 +841,33 @@ def test_format_code_no_docstring(self, test_args, args): ) assert docstring == uut._do_format_code(docstring) + @pytest.mark.unit + @pytest.mark.parametrize("args", [[""]]) + def test_format_code_class_docstring(self, test_args, args): + """Format class docstring.""" + uut = Formator( + test_args, + sys.stderr, + sys.stdin, + sys.stdout, + ) + + docstring = '''\ +class TestClass: + """This is a class docstring. + + :cvar test_int: a class attribute. + ..py.method: big_method() + """ +''' + assert docstring == uut._do_format_code('''\ +class TestClass: + """This is a class docstring. + :cvar test_int: a class attribute. + ..py.method: big_method() + """ +''') + class TestFormatCodeRanges: """Class for testing _format_code() with the line_range or length_range diff --git a/tests/test_format_docstring.py b/tests/test_format_docstring.py index f9c449d..7f73a18 100644 --- a/tests/test_format_docstring.py +++ b/tests/test_format_docstring.py @@ -839,7 +839,7 @@ def test_format_docstring_with_target_links( "args", [["--wrap-descriptions", "72", ""]], ) - def test_format_docstring_with_sinmple_link( + def test_format_docstring_with_simple_link( self, test_args, args, @@ -910,6 +910,35 @@ def test_format_docstring_with_short_link( INDENTATION, docstring.strip() ) + @pytest.mark.unit + @pytest.mark.parametrize("args", [[""]]) + def test_format_docstring_with_class_attributes(self, test_args, args): + """Wrap long class attribute docstrings.""" + uut = Formator( + test_args, + sys.stderr, + sys.stdin, + sys.stdout, + ) + + docstring = '''\ +class TestClass: + """This is a class docstring.""" + + test_int = 1 + """This is a very, very, very long docstring that should really be + reformatted nicely by docformatter.""" +''' + assert docstring == uut._do_format_code( + '''\ +class TestClass: + """This is a class docstring.""" + + test_int = 1 + """This is a very, very, very long docstring that should really be reformatted nicely by docformatter.""" +''' + ) + class TestFormatStyleOptions: """Class for testing format_docstring() when requesting style options.""" diff --git a/tests/test_string_functions.py b/tests/test_string_functions.py index a0ec0e2..423a9d9 100644 --- a/tests/test_string_functions.py +++ b/tests/test_string_functions.py @@ -189,6 +189,23 @@ def test_normalize_summary_formatted_as_title(self): summary = "# This is a title" assert summary == docformatter.normalize_summary(summary) + @pytest.mark.unit + def test_normalize_summary_capitalize_first_letter(self): + """Capitalize the first letter of the summary. + + See issue #76. See requirement docformatter_4.5.1. + """ + assert ( + "This is a summary that needs to be capped." + == docformatter.normalize_summary( + "this is a summary that needs to be capped" + ) + ) + + assert "Don't lower case I'm." == docformatter.normalize_summary( + "don't lower case I'm" + ) + class TestSplitters: """Class for testing the string splitting function.