diff options
-rw-r--r-- | tests/helpers.py | 24 | ||||
-rw-r--r-- | tests/test_process.py | 14 | ||||
-rw-r--r-- | tests/test_testing.py | 49 | ||||
-rw-r--r-- | tests/test_xml.py | 16 |
4 files changed, 72 insertions, 31 deletions
diff --git a/tests/helpers.py b/tests/helpers.py index a132872e..344ed71e 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -4,6 +4,7 @@ """Helpers for coverage.py tests.""" import os +import re import subprocess import sys @@ -77,3 +78,26 @@ class CheckUniqueFilenames(object): self.filenames.add(filename) ret = self.wrapped(filename, *args, **kwargs) return ret + + +def re_lines(text, pat, match=True): + """Return the text of lines that match `pat` in the string `text`. + + If `match` is false, the selection is inverted: only the non-matching + lines are included. + + Returns a string, the text of only the selected lines. + + """ + return "".join(l for l in text.splitlines(True) if bool(re.search(pat, l)) == match) + + +def re_line(text, pat): + """Return the one line in `text` that matches regex `pat`. + + Raises an AssertionError if more than one, or less than one, line matches. + + """ + lines = re_lines(text, pat).splitlines() + assert len(lines) == 1 + return lines[0] diff --git a/tests/test_process.py b/tests/test_process.py index d77dfda6..6ed566e4 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -18,6 +18,7 @@ from coverage import env, CoverageData from coverage.misc import output_encoding from tests.coveragetest import CoverageTest +from tests.helpers import re_lines class ProcessTest(CoverageTest): @@ -388,8 +389,7 @@ class ProcessTest(CoverageTest): out2 = self.run_command("python throw.py") if env.PYPY: # Pypy has an extra frame in the traceback for some reason - lines2 = out2.splitlines() - out2 = "".join(l+"\n" for l in lines2 if "toplevel" not in l) + out2 = re_lines(out2, "toplevel", match=False) self.assertMultiLineEqual(out, out2) # But also make sure that the output is what we expect. @@ -722,8 +722,8 @@ class EnvironmentTest(CoverageTest): # the comparison also... if env.PYPY: ignored += "|"+re.escape(os.getcwd()) - out_cov = remove_matching_lines(out_cov, ignored) - out_py = remove_matching_lines(out_py, ignored) + out_cov = re_lines(out_cov, ignored, match=False) + out_py = re_lines(out_py, ignored, match=False) self.assertMultiLineEqual(out_cov, out_py) self.assert_execfile_output(out_cov) @@ -1405,9 +1405,3 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): def test_script_pkg_sub(self): self.assert_pth_and_source_work_together('', 'pkg', 'sub') - - -def remove_matching_lines(text, pat): - """Return `text` with all lines matching `pat` removed.""" - lines = [l for l in text.splitlines(True) if not re.search(pat, l)] - return "".join(lines) diff --git a/tests/test_testing.py b/tests/test_testing.py index b74d08fb..a7f60b31 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -8,12 +8,14 @@ import datetime import os import sys +import pytest + import coverage from coverage.backunittest import TestCase from coverage.files import actual_path from tests.coveragetest import CoverageTest -from tests.helpers import CheckUniqueFilenames +from tests.helpers import CheckUniqueFilenames, re_lines, re_line class TestingTest(TestCase): @@ -131,12 +133,14 @@ class CoverageTestTest(CoverageTest): self.assertEqual(out[2], 'XYZZY') # Try it with a "coverage debug sys" command. - out = self.run_command("coverage debug sys").splitlines() - # "environment: COV_FOOBAR = XYZZY" or "COV_FOOBAR = XYZZY" - executable = next(l for l in out if "executable:" in l) # pragma: part covered + out = self.run_command("coverage debug sys") + + executable = re_line(out, "executable:") executable = executable.split(":", 1)[1].strip() - self.assertTrue(same_python_executable(executable, sys.executable)) - environ = next(l for l in out if "COV_FOOBAR" in l) # pragma: part covered + self.assertTrue(_same_python_executable(executable, sys.executable)) + + # "environment: COV_FOOBAR = XYZZY" or "COV_FOOBAR = XYZZY" + environ = re_line(out, "COV_FOOBAR") _, _, environ = environ.rpartition(":") self.assertEqual(environ.strip(), "COV_FOOBAR = XYZZY") @@ -168,7 +172,38 @@ class CheckUniqueFilenamesTest(CoverageTest): stub.method("file1") -def same_python_executable(e1, e2): +@pytest.mark.parametrize("text, pat, result", [ + ("line1\nline2\nline3\n", "line", "line1\nline2\nline3\n"), + ("line1\nline2\nline3\n", "[13]", "line1\nline3\n"), + ("line1\nline2\nline3\n", "X", ""), +]) +def test_re_lines(text, pat, result): + assert re_lines(text, pat) == result + +@pytest.mark.parametrize("text, pat, result", [ + ("line1\nline2\nline3\n", "line", ""), + ("line1\nline2\nline3\n", "[13]", "line2\n"), + ("line1\nline2\nline3\n", "X", "line1\nline2\nline3\n"), +]) +def test_re_lines_inverted(text, pat, result): + assert re_lines(text, pat, match=False) == result + +@pytest.mark.parametrize("text, pat, result", [ + ("line1\nline2\nline3\n", "2", "line2"), +]) +def test_re_line(text, pat, result): + assert re_line(text, pat) == result + +@pytest.mark.parametrize("text, pat", [ + ("line1\nline2\nline3\n", "line"), # too many matches + ("line1\nline2\nline3\n", "X"), # no matches +]) +def test_re_line_bad(text, pat): + with pytest.raises(AssertionError): + re_line(text, pat) + + +def _same_python_executable(e1, e2): """Determine if `e1` and `e2` refer to the same Python executable. Either path could include symbolic links. The two paths might not refer diff --git a/tests/test_xml.py b/tests/test_xml.py index dd14b920..9f1781af 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -13,6 +13,7 @@ from coverage.files import abs_file from tests.coveragetest import CoverageTest from tests.goldtest import CoverageGoldTest from tests.goldtest import change_dir, compare +from tests.helpers import re_line, re_lines class XmlTestHelpers(CoverageTest): @@ -194,7 +195,7 @@ class XmlPackageStructureTest(XmlTestHelpers, CoverageTest): cov.xml_report(outfile="-") packages_and_classes = re_lines(self.stdout(), r"<package |<class ") scrubs = r' branch-rate="0"| complexity="0"| line-rate="[\d.]+"' - return clean("".join(packages_and_classes), scrubs) + return clean(packages_and_classes, scrubs) def assert_package_and_class_tags(self, cov, result): """Check the XML package and class tags from `cov` match `result`.""" @@ -282,19 +283,6 @@ class XmlPackageStructureTest(XmlTestHelpers, CoverageTest): """) -def re_lines(text, pat): - """Return a list of lines that match `pat` in the string `text`.""" - lines = [l for l in text.splitlines(True) if re.search(pat, l)] - return lines - - -def re_line(text, pat): - """Return the one line in `text` that matches regex `pat`.""" - lines = re_lines(text, pat) - assert len(lines) == 1 - return lines[0] - - def clean(text, scrub=None): """Clean text to prepare it for comparison. |