nedbat / coveragepy

@@ -15,6 +15,7 @@
Loading
15 15
from coverage.python import get_python_source
16 16
17 17
from tests.coveragetest import CoverageTest, TESTS_DIR
18 +
from tests.helpers import re_lines
18 19
19 20
20 21
# A simple program and its token stream.
@@ -97,10 +98,15 @@
Loading
97 98
98 99
    def test_stress(self):
99 100
        # Check the tokenization of a stress-test file.
101 +
        # And check that those files haven't been incorrectly "fixed".
100 102
        stress = os.path.join(TESTS_DIR, "stress_phystoken.tok")
101 103
        self.check_file_tokenization(stress)
104 +
        with open(stress) as fstress:
105 +
            assert re_lines(fstress.read(), r"\s$"), f"{stress} needs a trailing space."
102 106
        stress = os.path.join(TESTS_DIR, "stress_phystoken_dos.tok")
103 107
        self.check_file_tokenization(stress)
108 +
        with open(stress) as fstress:
109 +
            assert re_lines(fstress.read(), r"\s$"), f"{stress} needs a trailing space."
104 110
105 111
106 112
@pytest.mark.skipif(not env.PYBEHAVIOR.soft_keywords, reason="Soft keywords are new in Python 3.10")

@@ -1306,7 +1306,7 @@
Loading
1306 1306
    """Is `value` simple enough to be displayed on a single line?"""
1307 1307
    return (
1308 1308
        value in [None, [], (), {}, set()] or
1309 -
        isinstance(value, (str, int, float))
1309 +
        isinstance(value, (bytes, int, float, str))
1310 1310
    )
1311 1311
1312 1312
def ast_dump(node, depth=0, print=print):   # pylint: disable=redefined-builtin
@@ -1352,7 +1352,10 @@
Loading
1352 1352
            elif isinstance(value, list):
1353 1353
                print(f"{prefix} [")
1354 1354
                for n in value:
1355 -
                    ast_dump(n, depth + 8, print=print)
1355 +
                    if _is_simple_value(n):
1356 +
                        print(f"{next_indent}    {n!r}")
1357 +
                    else:
1358 +
                        ast_dump(n, depth + 8, print=print)
1356 1359
                print(f"{next_indent}]")
1357 1360
            else:
1358 1361
                print(prefix)

@@ -4,7 +4,6 @@
Loading
4 4
"""Tests for coverage.py's code parsing."""
5 5
6 6
import os.path
7 -
import re
8 7
import textwrap
9 8
10 9
import pytest
@@ -14,7 +13,7 @@
Loading
14 13
from coverage.parser import ast_dump, ast_parse, PythonParser
15 14
16 15
from tests.coveragetest import CoverageTest, TESTS_DIR
17 -
from tests.helpers import arcz_to_arcs
16 +
from tests.helpers import arcz_to_arcs, re_lines
18 17
19 18
20 19
class PythonParserTest(CoverageTest):
@@ -485,17 +484,23 @@
Loading
485 484
    # Run the AST_DUMP code to make sure it doesn't fail, with some light
486 485
    # assertions. Use parser.py as the test code since it is the longest file,
487 486
    # and fitting, since it's the AST_DUMP code.
488 -
    parser_py = os.path.join(TESTS_DIR, "../coverage/parser.py")
489 -
    with open(parser_py) as f:
490 -
        ast_root = ast_parse(f.read())
491 -
    result = []
492 -
    ast_dump(ast_root, print=result.append)
493 -
    assert len(result) > 10000
494 -
    assert result[0] == "<Module"
495 -
    assert result[-1] == ">"
496 -
497 -
    def count(pat):
498 -
        return sum(1 for line in result if re.search(pat, line))
499 -
500 -
    assert count(r"^\s+>") > 2000
501 -
    assert count(r"<Name @ \d+,\d+(:\d+)? id: '\w+'>") > 1000
487 +
    files = [
488 +
        os.path.join(TESTS_DIR, "../coverage/parser.py"),
489 +
        os.path.join(TESTS_DIR, "stress_phystoken.tok"),
490 +
    ]
491 +
    for fname in files:
492 +
        with open(fname) as f:
493 +
            source = f.read()
494 +
            num_lines = len(source.splitlines())
495 +
            print(f"file {fname} has {num_lines} lines")
496 +
            ast_root = ast_parse(source)
497 +
        result = []
498 +
        ast_dump(ast_root, print=result.append)
499 +
        if num_lines < 100:
500 +
            continue
501 +
        assert len(result) > 5 * num_lines
502 +
        assert result[0] == "<Module"
503 +
        assert result[-1] == ">"
504 +
        result_text = "\n".join(result)
505 +
        assert len(re_lines(result_text, r"^\s+>")) > num_lines
506 +
        assert len(re_lines(result_text, r"<Name @ \d+,\d+(:\d+)? id: '\w+'>")) > num_lines // 2
Files Coverage
coverage 90.92%
tests 99.62%
__main__.py 100.00%
Project Totals (90 files) 96.15%

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading