def test_empty_decorated_function(self): parser = self.parse_source("""\ def decorator(func): return func @decorator def foo(self): '''Docstring''' @decorator def bar(self): pass """) if env.PYBEHAVIOR.trace_decorated_def: expected_statements = {1, 2, 4, 5, 8, 9, 10} expected_arcs = set( arcz_to_arcs(".1 14 45 58 89 9. .2 2. -8A A-8")) expected_exits = {1: 1, 2: 1, 4: 1, 5: 1, 8: 1, 9: 1, 10: 1} else: expected_statements = {1, 2, 4, 8, 10} expected_arcs = set(arcz_to_arcs(".1 14 48 8. .2 2. -8A A-8")) expected_exits = {1: 1, 2: 1, 4: 1, 8: 1, 10: 1} if env.PYBEHAVIOR.docstring_only_function: # 3.7 changed how functions with only docstrings are numbered. expected_arcs.update(set(arcz_to_arcs("-46 6-4"))) expected_exits.update({6: 1}) self.assertEqual(expected_statements, parser.statements) self.assertEqual(expected_arcs, parser.arcs()) self.assertEqual(expected_exits, parser.exit_counts())
def check_coverage( self, text, lines=None, missing="", report="", excludes=None, partials="", arcz=None, arcz_missing=None, arcz_unpredicted=None, arcs=None, arcs_missing=None, arcs_unpredicted=None, ): """Check the coverage measurement of `text`. The source `text` is run and measured. `lines` are the line numbers that are executable, or a list of possible line numbers, any of which could match. `missing` are the lines not executed, `excludes` are regexes to match against for excluding lines, and `report` is the text of the measurement report. For arc measurement, `arcz` is a string that can be decoded into arcs in the code (see `arcz_to_arcs` for the encoding scheme). `arcz_missing` are the arcs that are not executed, and `arcz_unpredicted` are the arcs executed in the code, but not deducible from the code. These last two default to "", meaning we explicitly check that there are no missing or unpredicted arcs. Returns the Coverage object, in case you want to poke at it some more. """ # We write the code into a file so that we can import it. # Coverage.py wants to deal with things as modules with file names. modname = self.get_module_name() self.make_file(modname + ".py", text) if arcs is None and arcz is not None: arcs = arcz_to_arcs(arcz) if arcs_missing is None and arcz_missing is not None: arcs_missing = arcz_to_arcs(arcz_missing) if arcs_unpredicted is None and arcz_unpredicted is not None: arcs_unpredicted = arcz_to_arcs(arcz_unpredicted) # Start up coverage.py. cov = coverage.Coverage(branch=True) cov.erase() for exc in excludes or []: cov.exclude(exc) for par in partials or []: cov.exclude(par, which='partial') mod = self.start_import_stop(cov, modname) # Clean up our side effects del sys.modules[modname] # Get the analysis results, and check that they are right. analysis = cov._analyze(mod) statements = sorted(analysis.statements) if lines is not None: if isinstance(lines[0], int): # lines is just a list of numbers, it must match the statements # found in the code. assert statements == lines, "{!r} != {!r}".format( statements, lines) else: # lines is a list of possible line number lists, one of them # must match. for line_list in lines: if statements == line_list: break else: self.fail("None of the lines choices matched %r" % statements) missing_formatted = analysis.missing_formatted() if isinstance(missing, string_class): msg = "{!r} != {!r}".format(missing_formatted, missing) assert missing_formatted == missing, msg else: for missing_list in missing: if missing_formatted == missing_list: break else: self.fail("None of the missing choices matched %r" % missing_formatted) if arcs is not None: # print("Possible arcs:") # print(" expected:", arcs) # print(" actual:", analysis.arc_possibilities()) # print("Executed:") # print(" actual:", sorted(set(analysis.arcs_executed()))) # TODO: this would be nicer with pytest-check, once we can run that. msg = ( self._check_arcs(arcs, analysis.arc_possibilities(), "Possible") + self._check_arcs(arcs_missing, analysis.arcs_missing(), "Missing") + self._check_arcs(arcs_unpredicted, analysis.arcs_unpredicted(), "Unpredicted")) if msg: assert False, msg if report: frep = StringIO() cov.report(mod, file=frep, show_missing=True) rep = " ".join(frep.getvalue().split("\n")[2].split()[1:]) assert report == rep, "{!r} != {!r}".format(report, rep) return cov
def test_arcz_to_arcs(arcz, arcs): assert arcz_to_arcs(arcz) == arcs