def test_simple(self): self.make_file("hello.py") files.set_relative_directory() self.assertEqual(files.relative_filename(u"hello.py"), u"hello.py") a = self.abs_path("hello.py") self.assertNotEqual(a, "hello.py") self.assertEqual(files.relative_filename(a), "hello.py")
def test_simple(self): self.make_file("hello.py") files.set_relative_directory() self.assertEqual(files.relative_filename("hello.py"), "hello.py") a = self.abs_path("hello.py") self.assertNotEqual(a, "hello.py") self.assertEqual(files.relative_filename(a), "hello.py")
def test_simple(self): self.make_file("hello.py") files.set_relative_directory() assert files.relative_filename(u"hello.py") == u"hello.py" a = self.abs_path("hello.py") assert a != "hello.py" assert files.relative_filename(a) == "hello.py"
def test_peer_directories(self): self.make_file("sub/proj1/file1.py") self.make_file("sub/proj2/file2.py") a1 = self.abs_path("sub/proj1/file1.py") a2 = self.abs_path("sub/proj2/file2.py") d = os.path.normpath("sub/proj1") self.chdir(d) files.set_relative_directory() self.assertEqual(files.relative_filename(a1), "file1.py") self.assertEqual(files.relative_filename(a2), a2)
def test_peer_directories(self): self.make_file("sub/proj1/file1.py") self.make_file("sub/proj2/file2.py") a1 = self.abs_path("sub/proj1/file1.py") a2 = self.abs_path("sub/proj2/file2.py") d = os.path.normpath("sub/proj1") os.chdir(d) files.set_relative_directory() self.assertEqual(files.relative_filename(a1), "file1.py") self.assertEqual(files.relative_filename(a2), a2)
def __init__(self, morf, coverage=None): self.coverage = coverage if hasattr(morf, '__file__'): filename = morf.__file__ elif isinstance(morf, types.ModuleType): # A module should have had .__file__, otherwise we can't use it. # This could be a PEP-420 namespace package. raise CoverageException("Module {0} has no file".format(morf)) else: filename = morf filename = source_for_file(files.unicode_filename(filename)) super(PythonFileReporter, self).__init__(files.canonical_filename(filename)) if hasattr(morf, '__name__'): name = morf.__name__.replace(".", os.sep) if os.path.basename(filename).startswith('__init__.'): name += os.sep + "__init__" name += ".py" name = files.unicode_filename(name) else: name = files.relative_filename(filename) self.relname = name self._source = None self._parser = None self._statements = None self._excluded = None
def _get_file_reporter(self, morf): """Get a FileReporter for a module or filename.""" plugin = None if isinstance(morf, string_class): abs_morf = abs_file(morf) plugin_name = self.data.plugin_data().get(abs_morf) if plugin_name: plugin = self.plugins.get(plugin_name) if plugin: file_reporter = plugin.file_reporter(abs_morf) if file_reporter is None: raise CoverageException( "Plugin %r did not provide a file reporter for %r." % ( plugin._coverage_plugin_name, morf ) ) else: file_reporter = PythonFileReporter(morf, self) # The FileReporter can have a name attribute, but if it doesn't, we'll # supply it as the relative path to self.filename. if not hasattr(file_reporter, "name"): file_reporter.name = files.relative_filename(file_reporter.filename) return file_reporter
def __init__(self, morf, coverage=None): self.coverage = coverage if hasattr(morf, '__file__'): filename = morf.__file__ elif isinstance(morf, types.ModuleType): # A module should have had .__file__, otherwise we can't use it. # This could be a PEP-420 namespace package. raise CoverageException("Module {0} has no file".format(morf)) else: filename = morf filename = files.unicode_filename(filename) # .pyc files should always refer to a .py instead. if filename.endswith(('.pyc', '.pyo')): filename = filename[:-1] elif filename.endswith('$py.class'): # Jython filename = filename[:-9] + ".py" super(PythonFileReporter, self).__init__(files.canonical_filename(filename)) if hasattr(morf, '__name__'): name = morf.__name__ name = name.replace(".", os.sep) + ".py" name = files.unicode_filename(name) else: name = files.relative_filename(filename) self.relname = name self._source = None self._parser = None self._statements = None self._excluded = None
def __init__(self, morf, coverage=None): self.coverage = coverage if hasattr(morf, '__file__'): filename = morf.__file__ else: filename = morf filename = files.unicode_filename(filename) # .pyc files should always refer to a .py instead. if filename.endswith(('.pyc', '.pyo')): filename = filename[:-1] elif filename.endswith('$py.class'): # Jython filename = filename[:-9] + ".py" super(PythonFileReporter, self).__init__(files.canonical_filename(filename)) if hasattr(morf, '__name__'): name = morf.__name__ name = name.replace(".", os.sep) + ".py" name = files.unicode_filename(name) else: name = files.relative_filename(filename) self.relname = name self._source = None self._parser = None self._statements = None self._excluded = None
def get_combined_filenames(): cov = coverage.Coverage() cov.combine() cov.save() data = cov.get_data() filenames = {relative_filename(f).replace("\\", "/") for f in data.measured_files()} return filenames
def relative_filename(self): """Return the relative filename for this file. This file path will be displayed in reports. You only need to supply this method if you have an unusual syntax for file paths. The default implementation will supply the actual project-relative file path. """ return files.relative_filename(self.filename)
def test_filepath_contains_absolute_prefix_twice(self): # https://bitbucket.org/ned/coveragepy/issue/194 # Build a path that has two pieces matching the absolute path prefix. # Technically, this test doesn't do that on Windows, but drive # letters make that impractical to achieve. files.set_relative_directory() d = abs_file(os.curdir) trick = os.path.splitdrive(d)[1].lstrip(os.path.sep) rel = os.path.join('sub', trick, 'file1.py') self.assertEqual(files.relative_filename(abs_file(rel)), rel)
def relative_filename(self): """Get the relative file name for this file. This file path will be displayed in reports. The default implementation will supply the actual project-relative file path. You only need to supply this method if you have an unusual syntax for file paths. """ return files.relative_filename(self.filename)
def convert_to_relative_paths(cls, smother_obj): data = defaultdict(lambda: dict()) set_relative_directory() for ctx, cover in smother_obj.data.items(): for src, lines in cover.items(): src = relative_filename(src) data[ctx][src] = lines result = cls() result.data = dict(data) return result
def __init__(self, morf, coverage=None): self.coverage = coverage filename = source_for_morf(morf) super().__init__(canonical_filename(filename)) if hasattr(morf, '__name__'): name = morf.__name__.replace(".", os.sep) if os.path.basename(filename).startswith('__init__.'): name += os.sep + "__init__" name += ".py" else: name = relative_filename(filename) self.relname = name self._source = None self._parser = None self._excluded = None
def __init__(self, morf, coverage=None): self.coverage = coverage filename = source_for_morf(morf) super(PythonFileReporter, self).__init__(files.canonical_filename(filename)) if hasattr(morf, '__name__'): name = morf.__name__.replace(".", os.sep) if os.path.basename(filename).startswith('__init__.'): name += os.sep + "__init__" name += ".py" name = files.unicode_filename(name) else: name = files.relative_filename(filename) self.relname = name self._source = None self._parser = None self._statements = None self._excluded = None
def create_tree_from_coverage(cov, strip_prefix=None, path_aliases=None): """Create a tree with coverage statistics. Takes a coverage.coverage() instance. Returns the root node of the tree. """ root = CoverageNode() if path_aliases: apply_path_aliases(cov, dict([alias.partition('=')[::2] for alias in path_aliases])) for filename in cov.data.measured_files(): if strip_prefix and filename.startswith(strip_prefix): short_name = filename[len(strip_prefix):] short_name = short_name.replace('/', os.path.sep) short_name = short_name.lstrip(os.path.sep) else: short_name = relative_filename(filename) tree_index = filename_to_list(short_name.replace(os.path.sep, '.')) if 'tests' in tree_index or 'ftests' in tree_index: continue root.set_at(tree_index, CoverageCoverageNode(cov, filename)) return root
def xml_file(self, fr, analysis): """Add to the XML report for a single file.""" # Create the 'lines' and 'package' XML elements, which # are populated later. Note that a package == a directory. filename = files.relative_filename(fr.filename) filename = filename.replace("\\", "/") dirname = os.path.dirname(filename) or "." parts = dirname.split("/") dirname = "/".join(parts[:self.config.xml_package_depth]) package_name = dirname.replace("/", ".") className = fr.name self.source_paths.add(files.relative_directory().rstrip('/')) package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0]) xclass = self.xml_out.createElement("class") xclass.appendChild(self.xml_out.createElement("methods")) xlines = self.xml_out.createElement("lines") xclass.appendChild(xlines) xclass.setAttribute("name", os.path.relpath(filename, dirname)) xclass.setAttribute("filename", filename) xclass.setAttribute("complexity", "0") branch_stats = analysis.branch_stats() # For each statement, create an XML 'line' element. for line in sorted(analysis.statements): xline = self.xml_out.createElement("line") xline.setAttribute("number", str(line)) # Q: can we get info about the number of times a statement is # executed? If so, that should be recorded here. xline.setAttribute("hits", str(int(line not in analysis.missing))) if self.arcs: if line in branch_stats: total, taken = branch_stats[line] xline.setAttribute("branch", "true") xline.setAttribute( "condition-coverage", "%d%% (%d/%d)" % (100*taken/total, taken, total) ) xlines.appendChild(xline) class_lines = len(analysis.statements) class_hits = class_lines - len(analysis.missing) if self.arcs: class_branches = sum(t for t, k in branch_stats.values()) missing_branches = sum(t - k for t, k in branch_stats.values()) class_br_hits = class_branches - missing_branches else: class_branches = 0.0 class_br_hits = 0.0 # Finalize the statistics that are collected in the XML DOM. xclass.setAttribute("line-rate", rate(class_hits, class_lines)) if self.arcs: branch_rate = rate(class_br_hits, class_branches) else: branch_rate = "0" xclass.setAttribute("branch-rate", branch_rate) package[0][className] = xclass package[1] += class_hits package[2] += class_lines package[3] += class_br_hits package[4] += class_branches
def relative_filename(self): return files.relative_filename(self.filename)
def xml_file(self, fr, analysis): """Add to the XML report for a single file.""" # Create the 'lines' and 'package' XML elements, which # are populated later. Note that a package == a directory. filename = files.relative_filename(fr.filename) filename = filename.replace("\\", "/") dirname = os.path.dirname(filename) or "." parts = dirname.split("/") dirname = "/".join(parts[:self.config.xml_package_depth]) package_name = dirname.replace("/", ".") className = fr.relative_filename() self.source_paths.add(files.relative_directory().rstrip('/')) package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0]) xclass = self.xml_out.createElement("class") xclass.appendChild(self.xml_out.createElement("methods")) xlines = self.xml_out.createElement("lines") xclass.appendChild(xlines) xclass.setAttribute("name", os.path.relpath(filename, dirname)) xclass.setAttribute("filename", filename) xclass.setAttribute("complexity", "0") branch_stats = analysis.branch_stats() missing_branch_arcs = analysis.missing_branch_arcs() # For each statement, create an XML 'line' element. for line in sorted(analysis.statements): xline = self.xml_out.createElement("line") xline.setAttribute("number", str(line)) # Q: can we get info about the number of times a statement is # executed? If so, that should be recorded here. xline.setAttribute("hits", str(int(line not in analysis.missing))) if self.arcs: if line in branch_stats: total, taken = branch_stats[line] xline.setAttribute("branch", "true") xline.setAttribute( "condition-coverage", "%d%% (%d/%d)" % (100*taken/total, taken, total) ) if line in missing_branch_arcs: annlines = ["exit" if b < 0 else str(b) for b in missing_branch_arcs[line]] xline.setAttribute("missing-branches", ",".join(annlines)) xlines.appendChild(xline) class_lines = len(analysis.statements) class_hits = class_lines - len(analysis.missing) if self.arcs: class_branches = sum(t for t, k in branch_stats.values()) missing_branches = sum(t - k for t, k in branch_stats.values()) class_br_hits = class_branches - missing_branches else: class_branches = 0.0 class_br_hits = 0.0 # Finalize the statistics that are collected in the XML DOM. xclass.setAttribute("line-rate", rate(class_hits, class_lines)) if self.arcs: branch_rate = rate(class_br_hits, class_branches) else: branch_rate = "0" xclass.setAttribute("branch-rate", branch_rate) package[0][className] = xclass package[1] += class_hits package[2] += class_lines package[3] += class_br_hits package[4] += class_branches
"ERROR: UNIT TESTS FAILED, PLEASE FIX BEFORE RUNNING COVERAGE:\n%s\n%s" % (output_stream.getvalue(), error_string) output_stream.close() cov.stop() print("Generating HTML report") cov.html_report(directory='coverage') print("Aggregating package stats") total_numbers = {} # Package name -> (Numbers: package coverage stats, dict: files per coverage bin) for filename in cov.get_data().measured_files(): file_reporter = PythonFileReporter(filename, cov) analysis = Analysis(cov.get_data(), file_reporter, abs_file) # If the package name does not contain more than 2 parts, it's a top-level file. package_path = pathlib.Path(relative_filename(filename)) package = ".".join(package_path.parts[:2 if len(package_path.parts) > 2 else 1]) package_stats = total_numbers.get(package) # Put all exactly 100% coverage files into the 80%-100% bin individual_coverage = min(4, int(analysis.numbers.pc_covered / 20.0)) if not package_stats: total_numbers[package] = (analysis.numbers, {individual_coverage: 1}) else: package_numbers, package_buckets = package_stats package_buckets[individual_coverage] = 1 + package_buckets.get(individual_coverage, 0) total_numbers[package] = (package_numbers + analysis.numbers, package_buckets) print("Generating R barplot script") with open(os.path.join('coverage', 'plotbars.R'), 'w') as barplot_script: