Skip to content

Commit

Permalink
mypy: test_testing.py test_version.py
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed Jan 8, 2023
1 parent 1321803 commit 65aad08
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 42 deletions.
82 changes: 46 additions & 36 deletions tests/test_testing.py
Expand Up @@ -3,17 +3,22 @@

"""Tests that our test infrastructure is really working!"""

from __future__ import annotations

import datetime
import os
import re
import sys
import warnings

from typing import List, Tuple

import pytest

import coverage
from coverage.exceptions import CoverageWarning
from coverage.files import actual_path
from coverage.types import TArc

from tests.coveragetest import CoverageTest
from tests.helpers import (
Expand All @@ -22,13 +27,13 @@
)


def test_xdist_sys_path_nuttiness_is_fixed():
def test_xdist_sys_path_nuttiness_is_fixed() -> None:
# See conftest.py:fix_xdist_sys_path
assert sys.path[1] != ''
assert os.environ.get('PYTHONPATH') is None


def test_assert_count_equal():
def test_assert_count_equal() -> None:
assert_count_equal(set(), set())
assert_count_equal({"a": 1, "b": 2}, ["b", "a"])
with pytest.raises(AssertionError):
Expand All @@ -40,7 +45,7 @@ def test_assert_count_equal():
class CoverageTestTest(CoverageTest):
"""Test the methods in `CoverageTest`."""

def test_file_exists(self):
def test_file_exists(self) -> None:
self.make_file("whoville.txt", "We are here!")
self.assert_exists("whoville.txt")
self.assert_doesnt_exist("shadow.txt")
Expand All @@ -51,7 +56,7 @@ def test_file_exists(self):
with pytest.raises(AssertionError, match=msg):
self.assert_exists("shadow.txt")

def test_file_count(self):
def test_file_count(self) -> None:
self.make_file("abcde.txt", "abcde")
self.make_file("axczz.txt", "axczz")
self.make_file("afile.txt", "afile")
Expand Down Expand Up @@ -82,8 +87,8 @@ def test_file_count(self):
with pytest.raises(AssertionError, match=msg):
self.assert_file_count("*.q", 10)

def test_assert_recent_datetime(self):
def now_delta(seconds):
def test_assert_recent_datetime(self) -> None:
def now_delta(seconds: int) -> datetime.datetime:
"""Make a datetime `seconds` seconds from now."""
return datetime.datetime.now() + datetime.timedelta(seconds=seconds)

Expand All @@ -103,7 +108,7 @@ def now_delta(seconds):
with pytest.raises(AssertionError):
self.assert_recent_datetime(now_delta(1), seconds=120)

def test_assert_warnings(self):
def test_assert_warnings(self) -> None:
cov = coverage.Coverage()

# Make a warning, it should catch it properly.
Expand Down Expand Up @@ -152,7 +157,7 @@ def test_assert_warnings(self):
with self.assert_warnings(cov, ["Hello there!"]):
raise ZeroDivisionError("oops")

def test_assert_no_warnings(self):
def test_assert_no_warnings(self) -> None:
cov = coverage.Coverage()

# Happy path: no warnings.
Expand All @@ -165,7 +170,7 @@ def test_assert_no_warnings(self):
with self.assert_warnings(cov, []):
cov._warn("Watch out!")

def test_sub_python_is_this_python(self):
def test_sub_python_is_this_python(self) -> None:
# Try it with a Python command.
self.set_environ('COV_FOOBAR', 'XYZZY')
self.make_file("showme.py", """\
Expand All @@ -174,10 +179,10 @@ def test_sub_python_is_this_python(self):
print(os.__file__)
print(os.environ['COV_FOOBAR'])
""")
out = self.run_command("python showme.py").splitlines()
assert actual_path(out[0]) == actual_path(sys.executable)
assert out[1] == os.__file__
assert out[2] == 'XYZZY'
out_lines = self.run_command("python showme.py").splitlines()
assert actual_path(out_lines[0]) == actual_path(sys.executable)
assert out_lines[1] == os.__file__
assert out_lines[2] == 'XYZZY'

# Try it with a "coverage debug sys" command.
out = self.run_command("coverage debug sys")
Expand All @@ -191,7 +196,7 @@ def test_sub_python_is_this_python(self):
_, _, environ = environ.rpartition(":")
assert environ.strip() == "COV_FOOBAR = XYZZY"

def test_run_command_stdout_stderr(self):
def test_run_command_stdout_stderr(self) -> None:
# run_command should give us both stdout and stderr.
self.make_file("outputs.py", """\
import sys
Expand All @@ -202,7 +207,7 @@ def test_run_command_stdout_stderr(self):
assert "StdOut\n" in out
assert "StdErr\n" in out

def test_stdout(self):
def test_stdout(self) -> None:
# stdout is captured.
print("This is stdout")
print("Line 2")
Expand All @@ -219,14 +224,19 @@ class CheckUniqueFilenamesTest(CoverageTest):

class Stub:
"""A stand-in for the class we're checking."""
def __init__(self, x):
def __init__(self, x: int) -> None:
self.x = x

def method(self, filename, a=17, b="hello"):
def method(
self,
filename: str,
a: int = 17,
b: str = "hello",
) -> Tuple[int, str, int, str]:
"""The method we'll wrap, with args to be sure args work."""
return (self.x, filename, a, b)

def test_detect_duplicate(self):
def test_detect_duplicate(self) -> None:
stub = self.Stub(23)
CheckUniqueFilenames.hook(stub, "method")

Expand Down Expand Up @@ -259,7 +269,7 @@ def oops(x):
ARCZ_MISSING = "3-2 78 8B"
ARCZ_UNPREDICTED = "79"

def test_check_coverage_possible(self):
def test_check_coverage_possible(self) -> None:
msg = r"(?s)Possible arcs differ: .*- \(6, 3\).*\+ \(6, 7\)"
with pytest.raises(AssertionError, match=msg):
self.check_coverage(
Expand All @@ -269,7 +279,7 @@ def test_check_coverage_possible(self):
arcz_unpredicted=self.ARCZ_UNPREDICTED,
)

def test_check_coverage_missing(self):
def test_check_coverage_missing(self) -> None:
msg = r"(?s)Missing arcs differ: .*- \(3, 8\).*\+ \(7, 8\)"
with pytest.raises(AssertionError, match=msg):
self.check_coverage(
Expand All @@ -279,7 +289,7 @@ def test_check_coverage_missing(self):
arcz_unpredicted=self.ARCZ_UNPREDICTED,
)

def test_check_coverage_unpredicted(self):
def test_check_coverage_unpredicted(self) -> None:
msg = r"(?s)Unpredicted arcs differ: .*- \(3, 9\).*\+ \(7, 9\)"
with pytest.raises(AssertionError, match=msg):
self.check_coverage(
Expand All @@ -300,7 +310,7 @@ class ReLinesTest(CoverageTest):
("[13]", "line1\nline2\nline3\n", "line1\nline3\n"),
("X", "line1\nline2\nline3\n", ""),
])
def test_re_lines(self, pat, text, result):
def test_re_lines(self, pat: str, text: str, result: str) -> None:
assert re_lines_text(pat, text) == result
assert re_lines(pat, text) == result.splitlines()

Expand All @@ -309,26 +319,26 @@ def test_re_lines(self, pat, text, result):
("[13]", "line1\nline2\nline3\n", "line2\n"),
("X", "line1\nline2\nline3\n", "line1\nline2\nline3\n"),
])
def test_re_lines_inverted(self, pat, text, result):
def test_re_lines_inverted(self, pat: str, text: str, result: str) -> None:
assert re_lines_text(pat, text, match=False) == result
assert re_lines(pat, text, match=False) == result.splitlines()

@pytest.mark.parametrize("pat, text, result", [
("2", "line1\nline2\nline3\n", "line2"),
])
def test_re_line(self, pat, text, result):
def test_re_line(self, pat: str, text: str, result: str) -> None:
assert re_line(pat, text) == result

@pytest.mark.parametrize("pat, text", [
("line", "line1\nline2\nline3\n"), # too many matches
("X", "line1\nline2\nline3\n"), # no matches
])
def test_re_line_bad(self, pat, text):
def test_re_line_bad(self, pat: str, text: str) -> None:
with pytest.raises(AssertionError):
re_line(pat, text)


def _same_python_executable(e1, e2):
def _same_python_executable(e1: str, e2: str) -> bool:
"""Determine if `e1` and `e2` refer to the same Python executable.
Either path could include symbolic links. The two paths might not refer
Expand Down Expand Up @@ -365,7 +375,7 @@ class ArczTest(CoverageTest):
("-11 12 2-5", [(-1, 1), (1, 2), (2, -5)]),
("-QA CB IT Z-A", [(-26, 10), (12, 11), (18, 29), (35, -10)]),
])
def test_arcz_to_arcs(self, arcz, arcs):
def test_arcz_to_arcs(self, arcz: str, arcs: List[TArc]) -> None:
assert arcz_to_arcs(arcz) == arcs

@pytest.mark.parametrize("arcs, arcz_repr", [
Expand All @@ -382,58 +392,58 @@ def test_arcz_to_arcs(self, arcz, arcs):
)
),
])
def test_arcs_to_arcz_repr(self, arcs, arcz_repr):
def test_arcs_to_arcz_repr(self, arcs: List[TArc], arcz_repr: str) -> None:
assert arcs_to_arcz_repr(arcs) == arcz_repr


class AssertCoverageWarningsTest(CoverageTest):
"""Tests of assert_coverage_warnings"""

def test_one_warning(self):
def test_one_warning(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("Hello there", category=CoverageWarning)
assert_coverage_warnings(warns, "Hello there")

def test_many_warnings(self):
def test_many_warnings(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("The first", category=CoverageWarning)
warnings.warn("The second", category=CoverageWarning)
warnings.warn("The third", category=CoverageWarning)
assert_coverage_warnings(warns, "The first", "The second", "The third")

def test_wrong_type(self):
def test_wrong_type(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("Not ours", category=Warning)
with pytest.raises(AssertionError):
assert_coverage_warnings(warns, "Not ours")

def test_wrong_message(self):
def test_wrong_message(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("Goodbye", category=CoverageWarning)
with pytest.raises(AssertionError):
assert_coverage_warnings(warns, "Hello there")

def test_wrong_number_too_many(self):
def test_wrong_number_too_many(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("The first", category=CoverageWarning)
warnings.warn("The second", category=CoverageWarning)
with pytest.raises(AssertionError):
assert_coverage_warnings(warns, "The first", "The second", "The third")

def test_wrong_number_too_few(self):
def test_wrong_number_too_few(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("The first", category=CoverageWarning)
warnings.warn("The second", category=CoverageWarning)
warnings.warn("The third", category=CoverageWarning)
with pytest.raises(AssertionError):
assert_coverage_warnings(warns, "The first", "The second")

def test_regex_matches(self):
def test_regex_matches(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("The first", category=CoverageWarning)
assert_coverage_warnings(warns, re.compile("f?rst"))

def test_regex_doesnt_match(self):
def test_regex_doesnt_match(self) -> None:
with pytest.warns(Warning) as warns:
warnings.warn("The first", category=CoverageWarning)
with pytest.raises(AssertionError):
Expand Down
8 changes: 5 additions & 3 deletions tests/test_version.py
Expand Up @@ -3,6 +3,8 @@

"""Tests of version.py."""

from __future__ import annotations

import coverage
from coverage.version import _make_url, _make_version

Expand All @@ -14,13 +16,13 @@ class VersionTest(CoverageTest):

run_in_temp_dir = False

def test_version_info(self):
def test_version_info(self) -> None:
# Make sure we didn't screw up the version_info tuple.
assert isinstance(coverage.version_info, tuple)
assert [type(d) for d in coverage.version_info] == [int, int, int, str, int]
assert coverage.version_info[3] in {'alpha', 'beta', 'candidate', 'final'}

def test_make_version(self):
def test_make_version(self) -> None:
assert _make_version(4, 0, 0, 'alpha') == "4.0.0a0"
assert _make_version(4, 0, 0, 'alpha', 1) == "4.0.0a1"
assert _make_version(4, 0, 0, 'final') == "4.0.0"
Expand All @@ -30,7 +32,7 @@ def test_make_version(self):
assert _make_version(5, 10, 2, 'candidate', 7) == "5.10.2rc7"
assert _make_version(5, 10, 2, 'candidate', 7, 3) == "5.10.2rc7.dev3"

def test_make_url(self):
def test_make_url(self) -> None:
assert _make_url(4, 0, 0, 'final') == "https://coverage.readthedocs.io"
expected = "https://coverage.readthedocs.io/en/4.1.2b3"
assert _make_url(4, 1, 2, 'beta', 3) == expected
Expand Down
7 changes: 4 additions & 3 deletions tox.ini
Expand Up @@ -106,9 +106,10 @@ setenv =
T3=tests/test_config.py tests/test_context.py tests/test_coverage.py tests/test_data.py tests/test_debug.py tests/test_execfile.py
T4=tests/test_filereporter.py tests/test_files.py tests/test_goldtest.py tests/test_html.py tests/test_json.py tests/test_lcov.py
T5=tests/test_misc.py tests/test_mixins.py tests/test_numbits.py tests/test_oddball.py tests/test_parser.py tests/test_phystokens.py
T6=tests/test_process.py tests/test_python.py tests/test_report.py tests/test_results.py tests/test_setup.py tests/test_summary.py tests/test_xml.py
# not done yet: test_plugins.py
TYPEABLE={env:C1} {env:C2} {env:C3} {env:C4} {env:C5} {env:C6} {env:T1} {env:T2} {env:T3} {env:T4} {env:T5} {env:T6}
T6=tests/test_process.py tests/test_python.py tests/test_report.py tests/test_results.py tests/test_setup.py
T7=tests/test_summary.py tests/test_testing.py tests/test_version.py tests/test_xml.py
# not done yet: test_plugins.py test_templite.py test_venv.py
TYPEABLE={env:C1} {env:C2} {env:C3} {env:C4} {env:C5} {env:C6} {env:T1} {env:T2} {env:T3} {env:T4} {env:T5} {env:T6} {env:T7}

commands =
# PYVERSIONS
Expand Down

0 comments on commit 65aad08

Please sign in to comment.