diff --git a/README.rst b/README.rst index 1db3f99..ce37647 100644 --- a/README.rst +++ b/README.rst @@ -365,6 +365,8 @@ Configure within your ``pyproject.toml`` (``interrogate`` will automatically det exclude = ["setup.py", "docs", "build"] ignore-regex = ["^get$", "^mock_.*", ".*BaseClass.*"] ext = [] + # possible values: sphinx (default), google + style = sphinx # possible values: 0 (minimal output), 1 (-v), 2 (-vv) verbose = 0 quiet = false @@ -399,6 +401,8 @@ Or configure within your ``setup.cfg`` (``interrogate`` will automatically detec exclude = setup.py,docs,build ignore-regex = ^get$,^mock_.*,.*BaseClass.* ext = [] + ; possible values: sphinx (default), google + style = sphinx ; possible values: 0 (minimal output), 1 (-v), 2 (-vv) verbose = 0 quiet = false @@ -539,6 +543,14 @@ To view all options available, run ``interrogate --help``: `-w/--whitelist-regex` invocations supported. + --style [sphinx|google] Style of docstrings to honor. Using `google` + will consider a class and its `__init__` + method both covered if there is either a + class-level docstring, or an `__init__` + method docstring, instead of enforcing both. + Mutually exclusive with `-i`/`--ignore-init` + flag. [default: sphinx] + -o, --output FILE Write output to a given FILE. [default: stdout] diff --git a/docs/changelog.rst b/docs/changelog.rst index 39ae202..02ea817 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,7 @@ Added * `tomli` dependency for Python versions < 3.11, making use of `tomllib` in the standard library with 3.11+ (`#150 `_). * Support for ``pyi`` file extensions (and leave room for other file extensions to be added, like maybe ``ipynb``). +* Support for Google-style docstrings for class ``__init__`` methods with new ``--style [sphinx|google]`` flag (`#128 `_). Fixed ^^^^^ diff --git a/docs/index.rst b/docs/index.rst index 0b48a88..10e2d79 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -102,6 +102,13 @@ Command Line Options Regex identifying class, method, and function names to include. Multiple ``-r/--ignore-regex`` invocations supported. +.. option:: --style [sphinx|google] + + Style of docstrings to honor. Using ``google`` will consider a class and its ``__init__`` method + both covered if there is either a class-level docstring, or an ``__init__`` method docstring, + instead of enforcing both. Mutually exclusive with ``-i/--ignore-init`` flag. + [default: ``sphinx``] + .. option:: -o, --output FILE Write output to a given ``FILE``. [default: ``stdout``] diff --git a/src/interrogate/cli.py b/src/interrogate/cli.py index a3f7ed9..ec71370 100644 --- a/src/interrogate/cli.py +++ b/src/interrogate/cli.py @@ -202,6 +202,18 @@ "Multiple `-w/--whitelist-regex` invocations supported." ), ) +@click.option( + "--style", + type=click.Choice(["sphinx", "google"]), + default="sphinx", + show_default=True, + help=( + "Style of docstrings to honor.\nUsing `google` will consider a class " + "and its `__init__` method both covered if there is either a class-" + "level docstring, or an `__init__` method docstring, instead of " + "enforcing both. Mutually exclusive with `-i`/`--ignore-init` flag." + ), +) @click.option( "-o", "--output", @@ -323,6 +335,7 @@ def main(ctx, paths, **kwargs): .. versionadded:: 1.5.0 ``--badge-style`` .. versionadded:: 1.6.0 ``--ignore-overloaded-functions`` .. verisonadded:: 1.7.0 ``--ext`` + .. versionadded:: 1.7.0 ``--style=sphinx|google`` .. versionchanged:: 1.3.1 only generate badge if results change from an existing badge. @@ -340,6 +353,14 @@ def main(ctx, paths, **kwargs): "The `--badge-style` option must be used along with the `-g/" "--generate-badge option." ) + if kwargs["style"] == "google" and kwargs["ignore_init_method"]: + raise click.BadOptionUsage( + option_name="style", + message=( + "The `--ignore-init-method` flag is mutually exclusive with " + "`--style google`." + ), + ) if not paths: paths = (os.path.abspath(os.getcwd()),) @@ -353,6 +374,7 @@ def main(ctx, paths, **kwargs): conf = config.InterrogateConfig( color=kwargs["color"], + docstring_style=kwargs["style"], fail_under=kwargs["fail_under"], ignore_regex=kwargs["ignore_regex"], ignore_magic=kwargs["ignore_magic"], diff --git a/src/interrogate/config.py b/src/interrogate/config.py index 97c60f6..073905e 100644 --- a/src/interrogate/config.py +++ b/src/interrogate/config.py @@ -25,6 +25,8 @@ class InterrogateConfig: """Configuration related to interrogating a given codebase. :param bool color: Highlight verbose output with color. + :param str docstring_style: Style of docstrings to follow. Choices: + "sphinx" (default), "google". :param fail_under: Fail when coverage % is less than a given amount. :type fail_under: `int` or `float` :param str ignore_regex: Regex identifying class, method, and @@ -48,7 +50,10 @@ class InterrogateConfig: functions. """ + VALID_STYLES = ("sphinx", "google") + color = attr.ib(default=False) + docstring_style = attr.ib(default="sphinx") fail_under = attr.ib(default=80.0) ignore_regex = attr.ib(default=False) ignore_magic = attr.ib(default=False) @@ -65,6 +70,15 @@ class InterrogateConfig: include_regex = attr.ib(default=False) omit_covered_files = attr.ib(default=False) + @docstring_style.validator + def _check_style(self, attribute, value): + """Validate selected choice for docstring style""" + if value not in self.VALID_STYLES: + raise ValueError( + f"Invalid `docstring_style` '{value}'. Valid values: " + f"{', '.join(self.VALID_STYLES)}" + ) + def find_project_root(srcs): """Return a directory containing .git, .hg, or pyproject.toml. diff --git a/src/interrogate/coverage.py b/src/interrogate/coverage.py index 6134c0a..ebf4bf7 100644 --- a/src/interrogate/coverage.py +++ b/src/interrogate/coverage.py @@ -212,6 +212,23 @@ def _filter_inner_nested(self, nodes): filtered_nodes = [n for n in filtered_nodes if n not in nested_cls] return filtered_nodes + def _set_google_style(self, nodes): + """Apply Google-style docstrings for class coverage. + + Update coverage of a class node if its `__init__` method has a + docstring, or an `__init__` method if its class has a docstring. + + A class and its `__init__` method are considered covered if either one + contains a docstring. See `_ for more info and an example. + """ + for node in nodes: + if node.node_type == "FunctionDef" and node.name == "__init__": + if not node.covered and node.parent.covered: + setattr(node, "covered", True) + elif node.covered and not node.parent.covered: + setattr(node.parent, "covered", True) + def _get_file_coverage(self, filename): """Get coverage results for a particular file.""" with open(filename, encoding="utf-8") as f: @@ -232,6 +249,9 @@ def _get_file_coverage(self, filename): if self.config.ignore_nested_classes: filtered_nodes = self._filter_inner_nested(filtered_nodes) + if self.config.docstring_style == "google": + self._set_google_style(filtered_nodes) + results = InterrogateFileResult( filename=filename, ignore_module=self.config.ignore_module, diff --git a/tests/functional/fixtures/expected_detailed.txt b/tests/functional/fixtures/expected_detailed.txt index ab463c5..b6dae0d 100644 --- a/tests/functional/fixtures/expected_detailed.txt +++ b/tests/functional/fixtures/expected_detailed.txt @@ -30,6 +30,10 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |------------------------------------------------------------------|-----------| | partial.py (module) | COVERED | | Foo (L8) | COVERED | diff --git a/tests/functional/fixtures/expected_detailed_no_module.txt b/tests/functional/fixtures/expected_detailed_no_module.txt index 46ccdd4..0ee8678 100644 --- a/tests/functional/fixtures/expected_detailed_no_module.txt +++ b/tests/functional/fixtures/expected_detailed_no_module.txt @@ -26,6 +26,10 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |------------------------------------------------------------------|-----------| | partial.py | | | Foo (L8) | COVERED | diff --git a/tests/functional/fixtures/expected_detailed_single_file.txt b/tests/functional/fixtures/expected_detailed_single_file.txt index 9da6727..499754a 100644 --- a/tests/functional/fixtures/expected_detailed_single_file.txt +++ b/tests/functional/fixtures/expected_detailed_single_file.txt @@ -26,12 +26,16 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |-----------------------------------------------------|------------------------| ----------------------------------- Summary ------------------------------------ | Name | Total | Miss | Cover | Cover% | |------------------|--------------|-------------|--------------|---------------| -| full.py | 25 | 0 | 25 | 100% | +| full.py | 29 | 0 | 29 | 100% | |------------------|--------------|-------------|--------------|---------------| -| TOTAL | 25 | 0 | 25 | 100.0% | +| TOTAL | 29 | 0 | 29 | 100.0% | --------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ---------------- diff --git a/tests/functional/fixtures/expected_no_verbosity.txt b/tests/functional/fixtures/expected_no_verbosity.txt index b88d658..fe17a21 100644 --- a/tests/functional/fixtures/expected_no_verbosity.txt +++ b/tests/functional/fixtures/expected_no_verbosity.txt @@ -1 +1 @@ -RESULT: FAILED (minimum: 80.0%, actual: 51.4%) +RESULT: FAILED (minimum: 80.0%, actual: 54.1%) diff --git a/tests/functional/fixtures/expected_summary.txt b/tests/functional/fixtures/expected_summary.txt index 89b7435..1457a6a 100644 --- a/tests/functional/fixtures/expected_summary.txt +++ b/tests/functional/fixtures/expected_summary.txt @@ -2,9 +2,9 @@ |------------------------------------------|--------|-------|--------|---------| | __init__.py | 1 | 0 | 1 | 100% | | empty.py | 1 | 1 | 0 | 0% | -| full.py | 25 | 0 | 25 | 100% | +| full.py | 29 | 0 | 29 | 100% | | partial.py | 29 | 19 | 10 | 34% | | child_sample/__init__.py | 1 | 1 | 0 | 0% | | child_sample/child_sample_module.py | 13 | 13 | 0 | 0% | |------------------------------------------|--------|-------|--------|---------| -| TOTAL | 70 | 34 | 36 | 51.4% | +| TOTAL | 74 | 34 | 40 | 54.1% | diff --git a/tests/functional/fixtures/expected_summary_no_module.txt b/tests/functional/fixtures/expected_summary_no_module.txt index 067e003..dd2ff83 100644 --- a/tests/functional/fixtures/expected_summary_no_module.txt +++ b/tests/functional/fixtures/expected_summary_no_module.txt @@ -1,9 +1,9 @@ ----------------------------------- Summary ------------------------------------ | Name | Total | Miss | Cover | Cover% | |------------------------------------------|--------|-------|--------|---------| -| full.py | 24 | 0 | 24 | 100% | +| full.py | 28 | 0 | 28 | 100% | | partial.py | 28 | 19 | 9 | 32% | | child_sample/child_sample_module.py | 12 | 12 | 0 | 0% | |------------------------------------------|--------|-------|--------|---------| -| TOTAL | 64 | 31 | 33 | 51.6% | ----------------- RESULT: FAILED (minimum: 80.0%, actual: 51.6%) ---------------- +| TOTAL | 68 | 31 | 37 | 54.4% | +---------------- RESULT: FAILED (minimum: 80.0%, actual: 54.4%) ---------------- diff --git a/tests/functional/fixtures/expected_summary_skip_covered.txt b/tests/functional/fixtures/expected_summary_skip_covered.txt index 9590ccd..21f63f9 100644 --- a/tests/functional/fixtures/expected_summary_skip_covered.txt +++ b/tests/functional/fixtures/expected_summary_skip_covered.txt @@ -5,6 +5,6 @@ | child_sample/__init__.py | 1 | 1 | 0 | 0% | | child_sample/child_sample_module.py | 13 | 13 | 0 | 0% | |------------------------------------------|--------|-------|--------|---------| -| TOTAL | 70 | 34 | 36 | 51.4% | +| TOTAL | 74 | 34 | 40 | 54.1% | |------------------------------------------------------------------------------| | (2 of 6 files omitted due to complete coverage) | diff --git a/tests/functional/fixtures/expected_summary_skip_covered_all.txt b/tests/functional/fixtures/expected_summary_skip_covered_all.txt index 31d18f7..e57b0e8 100644 --- a/tests/functional/fixtures/expected_summary_skip_covered_all.txt +++ b/tests/functional/fixtures/expected_summary_skip_covered_all.txt @@ -1,5 +1,5 @@ | Name | Total | Miss | Cover | Cover% | |------------------|--------------|-------------|--------------|---------------| -| TOTAL | 25 | 0 | 25 | 100.0% | +| TOTAL | 29 | 0 | 29 | 100.0% | |------------------------------------------------------------------------------| | (1 of 1 file omitted due to complete coverage) | diff --git a/tests/functional/fixtures/windows/expected_detailed.txt b/tests/functional/fixtures/windows/expected_detailed.txt index 14d8b98..1029262 100644 --- a/tests/functional/fixtures/windows/expected_detailed.txt +++ b/tests/functional/fixtures/windows/expected_detailed.txt @@ -30,6 +30,10 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |-----------------------------------------------------------------|-----------| | partial.py (module) | COVERED | | Foo (L8) | COVERED | diff --git a/tests/functional/fixtures/windows/expected_detailed_no_module.txt b/tests/functional/fixtures/windows/expected_detailed_no_module.txt index dd5df8b..fa5489e 100644 --- a/tests/functional/fixtures/windows/expected_detailed_no_module.txt +++ b/tests/functional/fixtures/windows/expected_detailed_no_module.txt @@ -26,6 +26,10 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |-----------------------------------------------------------------|-----------| | partial.py | | | Foo (L8) | COVERED | @@ -75,9 +79,9 @@ ----------------------------------- Summary ----------------------------------- | Name | Total | Miss | Cover | Cover% | |-----------------------------------------|--------|-------|--------|---------| -| full.py | 24 | 0 | 24 | 100% | +| full.py | 28 | 0 | 28 | 100% | | partial.py | 28 | 19 | 9 | 32% | | child_sample\child_sample_module.py | 12 | 12 | 0 | 0% | |-----------------------------------------|--------|-------|--------|---------| -| TOTAL | 64 | 31 | 33 | 51.6% | ---------------- RESULT: FAILED (minimum: 80.0%, actual: 51.6%) ---------------- +| TOTAL | 68 | 31 | 37 | 54.4% | +--------------- RESULT: FAILED (minimum: 80.0%, actual: 54.4%) ---------------- diff --git a/tests/functional/fixtures/windows/expected_detailed_single_file.txt b/tests/functional/fixtures/windows/expected_detailed_single_file.txt index 7020239..4382f70 100644 --- a/tests/functional/fixtures/windows/expected_detailed_single_file.txt +++ b/tests/functional/fixtures/windows/expected_detailed_single_file.txt @@ -26,12 +26,16 @@ | Bar.method_bar.InnerBar (L97) | COVERED | | _SemiprivateClass (L103) | COVERED | | __PrivateClass (L109) | COVERED | +| InitDocs (L116) | COVERED | +| InitDocs.__init__ (L117) | COVERED | +| ClassDocs (L123) | COVERED | +| ClassDocs.__init__ (L126) | COVERED | |----------------------------------------------------|------------------------| ----------------------------------- Summary ----------------------------------- | Name | Total | Miss | Cover | Cover% | |-----------------|--------------|-------------|--------------|---------------| -| full.py | 25 | 0 | 25 | 100% | +| full.py | 29 | 0 | 29 | 100% | |-----------------|--------------|-------------|--------------|---------------| -| TOTAL | 25 | 0 | 25 | 100.0% | +| TOTAL | 29 | 0 | 29 | 100.0% | --------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) --------------- diff --git a/tests/functional/fixtures/windows/expected_no_verbosity.txt b/tests/functional/fixtures/windows/expected_no_verbosity.txt index b88d658..fe17a21 100644 --- a/tests/functional/fixtures/windows/expected_no_verbosity.txt +++ b/tests/functional/fixtures/windows/expected_no_verbosity.txt @@ -1 +1 @@ -RESULT: FAILED (minimum: 80.0%, actual: 51.4%) +RESULT: FAILED (minimum: 80.0%, actual: 54.1%) diff --git a/tests/functional/fixtures/windows/expected_summary.txt b/tests/functional/fixtures/windows/expected_summary.txt index ef885ad..81b639f 100644 --- a/tests/functional/fixtures/windows/expected_summary.txt +++ b/tests/functional/fixtures/windows/expected_summary.txt @@ -2,9 +2,9 @@ |-----------------------------------------|--------|-------|--------|---------| | __init__.py | 1 | 0 | 1 | 100% | | empty.py | 1 | 1 | 0 | 0% | -| full.py | 25 | 0 | 25 | 100% | +| full.py | 29 | 0 | 29 | 100% | | partial.py | 29 | 19 | 10 | 34% | | child_sample\__init__.py | 1 | 1 | 0 | 0% | | child_sample\child_sample_module.py | 13 | 13 | 0 | 0% | |-----------------------------------------|--------|-------|--------|---------| -| TOTAL | 70 | 34 | 36 | 51.4% | +| TOTAL | 74 | 34 | 40 | 54.1% | diff --git a/tests/functional/fixtures/windows/expected_summary_no_module.txt b/tests/functional/fixtures/windows/expected_summary_no_module.txt index 99118ed..38b5edf 100644 --- a/tests/functional/fixtures/windows/expected_summary_no_module.txt +++ b/tests/functional/fixtures/windows/expected_summary_no_module.txt @@ -1,8 +1,8 @@ ----------------------------------- Summary ----------------------------------- | Name | Total | Miss | Cover | Cover% | |-----------------------------------------|--------|-------|--------|---------| -| full.py | 24 | 0 | 24 | 100% | +| full.py | 28 | 0 | 28 | 100% | | partial.py | 28 | 19 | 9 | 32% | | child_sample\child_sample_module.py | 12 | 12 | 0 | 0% | |-----------------------------------------|--------|-------|--------|---------| -| TOTAL | 64 | 31 | 33 | 51.6% | +| TOTAL | 68 | 31 | 37 | 54.4% | diff --git a/tests/functional/fixtures/windows/expected_summary_skip_covered.txt b/tests/functional/fixtures/windows/expected_summary_skip_covered.txt index 3299195..d37a628 100644 --- a/tests/functional/fixtures/windows/expected_summary_skip_covered.txt +++ b/tests/functional/fixtures/windows/expected_summary_skip_covered.txt @@ -5,4 +5,4 @@ | child_sample\__init__.py | 1 | 1 | 0 | 0% | | child_sample\child_sample_module.py | 13 | 13 | 0 | 0% | |-----------------------------------------|--------|-------|--------|---------| -| TOTAL | 70 | 34 | 36 | 51.4% | +| TOTAL | 74 | 34 | 40 | 54.1% | diff --git a/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt b/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt index 905dc50..a4a829f 100644 --- a/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt +++ b/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt @@ -1,7 +1,7 @@ ----------------------------------- Summary ----------------------------------- | Name | Total | Miss | Cover | Cover% | |-----------------|--------------|-------------|--------------|---------------| -| TOTAL | 25 | 0 | 25 | 100.0% | +| TOTAL | 29 | 0 | 29 | 100.0% | |-----------------------------------------------------------------------------| | (1 of 1 file omitted due to complete coverage) | --------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) --------------- diff --git a/tests/functional/sample/full.py b/tests/functional/sample/full.py index 06c66ba..9c97f90 100644 --- a/tests/functional/sample/full.py +++ b/tests/functional/sample/full.py @@ -110,3 +110,18 @@ class __PrivateClass: """a private class""" pass + + +# Coverage % for InitDocs should be the same as ClassDocs +class InitDocs: + def __init__(self): + """A docstring for init""" + pass + + +# Coverage % for ClassDocs should be the same as InitDocs +class ClassDocs: + """A docstring for a class""" + + def __init__(self): + pass diff --git a/tests/functional/sample/full.pyi b/tests/functional/sample/full.pyi index 3ebe6c6..fe25f47 100644 --- a/tests/functional/sample/full.pyi +++ b/tests/functional/sample/full.pyi @@ -83,3 +83,15 @@ class _SemiprivateClass: class __PrivateClass: """a private class""" + +# Coverage % for InitDocs should be the same as ClassDocs +class InitDocs: + def __init__(self) -> None: + """A docstring for init""" + +# Coverage % for ClassDocs should be the same as InitDocs +class ClassDocs: + """A docstring for a class""" + + def __init__(self) -> None: + pass diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py index e65f046..f4ae5b3 100644 --- a/tests/functional/test_cli.py +++ b/tests/functional/test_cli.py @@ -43,33 +43,33 @@ def test_run_no_paths(runner, monkeypatch, tmpdir): # no flags ([], 51.4, 1), # ignore init module - (["-I"], 51.5, 1), + (["-I"], 51.4, 1), # ignore module docs - (["-M"], 51.6, 1), + (["-M"], 51.5, 1), # ignore semiprivate docs - (["-s"], 52.4, 1), + (["-s"], 52.2, 1), # ignore private docs - (["-p"], 53.1, 1), + (["-p"], 52.9, 1), # ignore property getter/setter/deleter decorators (["-P"], 50.0, 1), # ignore property setter decorators - (["-S"], 51.5, 1), + (["-S"], 51.4, 1), # ignore magic method docs - (["-m"], 51.5, 1), + (["-m"], 51.4, 1), # ignore init method docs (["-i"], 50.7, 1), # ignore nested funcs (["-n"], 50.7, 1), # ignore nested classes - (["-C"], 52.2, 1), + (["-C"], 52.1, 1), # ignore @typing.overload-decorated functions - (["-O"], 51.6, 1), + (["-O"], 51.5, 1), # ignore regex - (["-r", "^get$"], 51.5, 1), + (["-r", "^get$"], 51.4, 1), # whitelist regex (["-w", "^get$"], 50.0, 1), # exclude file - (["-e", os.path.join(SAMPLE_DIR, "partial.py")], 63.4, 1), + (["-e", os.path.join(SAMPLE_DIR, "partial.py")], 62.2, 1), # exclude file which doesn't exist (["-e", os.path.join(SAMPLE_DIR, "does.not.exist")], 51.4, 1), # fail under @@ -89,22 +89,23 @@ def test_run_shortflags(flags, exp_result, exp_exit_code, runner): @pytest.mark.parametrize( "flags,exp_result,exp_exit_code", ( - (["--ignore-init-module"], 51.5, 1), - (["--ignore-module"], 51.6, 1), - (["--ignore-semiprivate"], 52.4, 1), - (["--ignore-private"], 53.1, 1), + (["--ignore-init-module"], 51.4, 1), + (["--ignore-module"], 51.5, 1), + (["--ignore-semiprivate"], 52.2, 1), + (["--ignore-private"], 52.9, 1), (["--ignore-property-decorators"], 50.0, 1), - (["--ignore-setters"], 51.5, 1), - (["--ignore-magic"], 51.5, 1), + (["--ignore-setters"], 51.4, 1), + (["--ignore-magic"], 51.4, 1), (["--ignore-init-method"], 50.7, 1), (["--ignore-nested-functions"], 50.7, 1), - (["--ignore-nested-classes"], 52.2, 1), - (["--ignore-overloaded-functions"], 51.6, 1), - (["--ignore-regex", "^get$"], 51.5, 1), - (["--ext", "pyi"], 64.2, 1), + (["--ignore-nested-classes"], 52.1, 1), + (["--ignore-overloaded-functions"], 51.5, 1), + (["--ignore-regex", "^get$"], 51.4, 1), + (["--ext", "pyi"], 63.1, 1), (["--whitelist-regex", "^get$"], 50.0, 1), - (["--exclude", os.path.join(SAMPLE_DIR, "partial.py")], 63.4, 1), + (["--exclude", os.path.join(SAMPLE_DIR, "partial.py")], 62.2, 1), (["--fail-under", "40"], 51.4, 0), + (["--style", "google"], 54.1, 1), ), ) def test_run_longflags(flags, exp_result, exp_exit_code, runner): @@ -121,8 +122,8 @@ def test_run_longflags(flags, exp_result, exp_exit_code, runner): "flags,exp_result,exp_exit_code", ( (["-i", "-I", "-r" "^method_foo$"], 51.6, 1), - (["-s", "-p", "-M"], 54.9, 1), - (["-m", "-f", "45"], 51.5, 0), + (["-s", "-p", "-M"], 54.5, 1), + (["-m", "-f", "45"], 51.4, 0), ), ) def test_run_multiple_flags(flags, exp_result, exp_exit_code, runner): diff --git a/tests/functional/test_coverage.py b/tests/functional/test_coverage.py index 214d87a..47906d0 100644 --- a/tests/functional/test_coverage.py +++ b/tests/functional/test_coverage.py @@ -44,7 +44,7 @@ def patch_term_width(monkeypatch): SAMPLE_DIR, ], {}, - (70, 36, 34, "51.4"), + (74, 38, 36, "51.4"), ), ([os.path.join(SAMPLE_DIR, "partial.py")], {}, (29, 10, 19, "34.5")), ( @@ -52,7 +52,7 @@ def patch_term_width(monkeypatch): os.path.join(SAMPLE_DIR, "full.py"), ], {"ignore_nested_functions": True}, - (24, 24, 0, "100.0"), + (28, 26, 2, "92.9"), ), ( [ @@ -66,7 +66,7 @@ def patch_term_width(monkeypatch): os.path.join(SAMPLE_DIR, "full.py"), ], {"ignore_overloaded_functions": True}, - (21, 21, 0, "100.0"), + (25, 23, 2, "92.0"), ), ( [ @@ -123,7 +123,10 @@ def test_coverage_errors(capsys): ) def test_print_results(level, exp_fixture_file, capsys, monkeypatch): """Output of test results differ by verbosity.""" - interrogate_coverage = coverage.InterrogateCoverage(paths=[SAMPLE_DIR]) + interrogate_config = config.InterrogateConfig(docstring_style="google") + interrogate_coverage = coverage.InterrogateCoverage( + paths=[SAMPLE_DIR], conf=interrogate_config + ) results = interrogate_coverage.get_coverage() interrogate_coverage.print_results( results=results, output=None, verbosity=level @@ -152,7 +155,9 @@ def test_print_results_omit_covered( level, exp_fixture_file, capsys, monkeypatch ): """Output of results differ by verbosity, omitting fully covered files.""" - interrogate_config = config.InterrogateConfig(omit_covered_files=True) + interrogate_config = config.InterrogateConfig( + omit_covered_files=True, docstring_style="google" + ) interrogate_coverage = coverage.InterrogateCoverage( paths=[SAMPLE_DIR], conf=interrogate_config ) @@ -190,7 +195,9 @@ def test_print_results_omit_none(level, capsys, monkeypatch): def test_print_results_omit_all_summary(capsys, monkeypatch): """Output of test results for summary view, omitting all covered files.""" - interrogate_config = config.InterrogateConfig(omit_covered_files=True) + interrogate_config = config.InterrogateConfig( + omit_covered_files=True, docstring_style="google" + ) interrogate_coverage = coverage.InterrogateCoverage( paths=[os.path.join(SAMPLE_DIR, "full.py")], conf=interrogate_config ) @@ -212,7 +219,9 @@ def test_print_results_omit_all_summary(capsys, monkeypatch): def test_print_results_omit_all_detailed(capsys, monkeypatch): """Show no detail view when all files are omitted from skipping covered""" - interrogate_config = config.InterrogateConfig(omit_covered_files=True) + interrogate_config = config.InterrogateConfig( + omit_covered_files=True, docstring_style="google" + ) interrogate_coverage = coverage.InterrogateCoverage( paths=[os.path.join(SAMPLE_DIR, "full.py")], conf=interrogate_config ) @@ -240,7 +249,7 @@ def test_print_results_ignore_module( ignore_module, level, exp_fixture_file, capsys, monkeypatch ): """Do not print module info if ignore_module is True.""" - conf = {"ignore_module": ignore_module} + conf = {"ignore_module": ignore_module, "docstring_style": "google"} conf = config.InterrogateConfig(**conf) interrogate_coverage = coverage.InterrogateCoverage( @@ -264,7 +273,11 @@ def test_print_results_ignore_module( def test_print_results_single_file(capsys, monkeypatch): """Results for a single file should still list the filename.""" single_file = os.path.join(SAMPLE_DIR, "full.py") - interrogate_coverage = coverage.InterrogateCoverage(paths=[single_file]) + conf = {"docstring_style": "google"} + conf = config.InterrogateConfig(**conf) + interrogate_coverage = coverage.InterrogateCoverage( + paths=[single_file], conf=conf + ) results = interrogate_coverage.get_coverage() interrogate_coverage.print_results( results=results, output=None, verbosity=2