diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2018-08-24 07:13:42 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2018-08-24 07:13:42 -0400 |
commit | c4b2392dd51b7f976972afb00f01d4618c523cff (patch) | |
tree | 7c77b420d4eec7ac628393663c67c0e9bc2c66f7 | |
parent | 8a337f91e6444c027771741a56636a56389706e3 (diff) | |
parent | dd5b0cc88ebe4528abaa7cdf0b3fd516fb1f7e01 (diff) | |
download | python-coveragepy-git-c4b2392dd51b7f976972afb00f01d4618c523cff.tar.gz |
Merge branch 'nedbat/data-sqlite'
90 files changed, 1789 insertions, 1426 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 4deb575d..ce645543 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -17,6 +17,15 @@ Change history for Coverage.py Unreleased ---------- +- Coverage's data storage has changed. In version 4.x, .coverage files were + basically JSON. Now, they are SQLite databases. This means the data file + can be created earlier than it used to. A large amount of code was + refactored to support this change. + +- The old data format is still available (for now) by setting the environment + variable COVERAGE_STORAGE=json. Please tell me if you think you need to keep + the JSON format. + - Development moved from `Bitbucket`_ to `GitHub`_. - HTML files no longer have trailing and extra whitespace. @@ -21,6 +21,7 @@ clean: -rm -f coverage/*,cover -rm -f MANIFEST -rm -f .coverage .coverage.* coverage.xml .metacov* + -rm -f */.coverage */*/.coverage */*/*/.coverage */*/*/*/.coverage */*/*/*/*/.coverage */*/*/*/*/*/.coverage -rm -f tests/zipmods.zip -rm -rf tests/eggsrc/build tests/eggsrc/dist tests/eggsrc/*.egg-info -rm -f setuptools-*.egg distribute-*.egg distribute-*.tar.gz @@ -30,7 +31,7 @@ clean: sterile: clean -rm -rf .tox* - -docker image rm quay.io/pypa/manylinux1_i686 quay.io/pypa/manylinux1_x86_64 + -docker image rm -f quay.io/pypa/manylinux1_i686 quay.io/pypa/manylinux1_x86_64 LINTABLE = coverage tests igor.py setup.py __main__.py @@ -47,13 +48,13 @@ pep8: test: tox -e py27,py35 $(ARGS) -TOX_SMOKE_ARGS = -n 6 -m "not expensive" --maxfail=3 $(ARGS) +PYTEST_SMOKE_ARGS = -n 6 -m "not expensive" --maxfail=3 $(ARGS) smoke: - COVERAGE_NO_PYTRACER=1 tox -e py27,py34 -- $(TOX_SMOKE_ARGS) + COVERAGE_NO_PYTRACER=1 tox -q -e py27,py34 -- $(PYTEST_SMOKE_ARGS) pysmoke: - COVERAGE_NO_CTRACER=1 tox -e py27,py34 -- $(TOX_SMOKE_ARGS) + COVERAGE_NO_CTRACER=1 tox -q -e py27,py34 -- $(PYTEST_SMOKE_ARGS) metacov: COVERAGE_COVERAGE=yes tox $(ARGS) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 2b8e8fb9..23d2aec3 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -14,6 +14,7 @@ import traceback from coverage import env from coverage.collector import CTracer +from coverage.data import line_counts from coverage.debug import info_formatter, info_header from coverage.execfile import run_python_file, run_python_module from coverage.misc import BaseCoverageException, ExceptionDuringRun, NoSource @@ -657,10 +658,10 @@ class CoverageScript(object): self.coverage.load() data = self.coverage.get_data() print(info_header("data")) - print("path: %s" % self.coverage._data_files.filename) + print("path: %s" % self.coverage.get_data().filename) if data: print("has_arcs: %r" % data.has_arcs()) - summary = data.line_counts(fullpath=True) + summary = line_counts(data, fullpath=True) filenames = sorted(summary.keys()) print("\n%d files:" % len(filenames)) for f in filenames: diff --git a/coverage/control.py b/coverage/control.py index 03238910..4dd62e10 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -15,7 +15,7 @@ from coverage.annotate import AnnotateReporter from coverage.backward import string_class, iitems from coverage.collector import Collector from coverage.config import read_coverage_config -from coverage.data import CoverageData, CoverageDataFiles +from coverage.data import CoverageData, combine_parallel_data from coverage.debug import DebugControl, write_formatted_info from coverage.disposition import disposition_debug_msg from coverage.files import PathAliases, set_relative_directory, abs_file @@ -152,7 +152,7 @@ class Coverage(object): self._warnings = [] # Other instance attributes, set later. - self._data = self._data_files = self._collector = None + self._data = self._collector = None self._plugins = None self._inorout = None self._inorout_class = InOrOut @@ -163,8 +163,11 @@ class Coverage(object): # State machine variables: # Have we initialized everything? self._inited = False + self._inited_for_start = False # Have we started collecting and not stopped it? self._started = False + # Have we written --debug output? + self._wrote_debug = False # If we have sub-process measurement happening automatically, then we # want any explicit creation of a Coverage object to mean, this process @@ -214,74 +217,11 @@ class Coverage(object): # this is a bit childish. :) plugin.configure([self, self.config][int(time.time()) % 2]) - concurrency = self.config.concurrency or [] - if "multiprocessing" in concurrency: - if not patch_multiprocessing: - raise CoverageException( # pragma: only jython - "multiprocessing is not supported on this Python" - ) - patch_multiprocessing(rcfile=self.config.config_file) - # Multi-processing uses parallel for the subprocesses, so also use - # it for the main process. - self.config.parallel = True - - self._collector = Collector( - should_trace=self._should_trace, - check_include=self._check_include_omit_etc, - timid=self.config.timid, - branch=self.config.branch, - warn=self._warn, - concurrency=concurrency, - ) - - # Early warning if we aren't going to be able to support plugins. - if self._plugins.file_tracers and not self._collector.supports_plugins: - self._warn( - "Plugin file tracers (%s) aren't supported with %s" % ( - ", ".join( - plugin._coverage_plugin_name - for plugin in self._plugins.file_tracers - ), - self._collector.tracer_name(), - ) - ) - for plugin in self._plugins.file_tracers: - plugin._coverage_enabled = False - - # Create the file classifying substructure. - self._inorout = self._inorout_class(warn=self._warn) - self._inorout.configure(self.config) - self._inorout.plugins = self._plugins - self._inorout.disp_class = self._collector.file_disposition_class - - # Suffixes are a bit tricky. We want to use the data suffix only when - # collecting data, not when combining data. So we save it as - # `self._run_suffix` now, and promote it to `self._data_suffix` if we - # find that we are collecting data later. - if self._data_suffix_specified or self.config.parallel: - if not isinstance(self._data_suffix_specified, string_class): - # if data_suffix=True, use .machinename.pid.random - self._data_suffix_specified = True - else: - self._data_suffix_specified = None - self._data_suffix = None - self._run_suffix = self._data_suffix_specified - - # Create the data file. We do this at construction time so that the - # data file will be written into the directory where the process - # started rather than wherever the process eventually chdir'd to. - self._data = CoverageData(debug=self._debug) - self._data_files = CoverageDataFiles( - basename=self.config.data_file, warn=self._warn, debug=self._debug, - ) - - # Set the reporting precision. - Numbers.set_precision(self.config.precision) - - atexit.register(self._atexit) - - # The user may want to debug things, show info if desired. - self._write_startup_debug() + def _post_init(self): + """Stuff to do after everything is initialized.""" + if not self._wrote_debug: + self._wrote_debug = True + self._write_startup_debug() def _write_startup_debug(self): """Write out debug info at startup if needed.""" @@ -388,8 +328,78 @@ class Coverage(object): def load(self): """Load previously-collected coverage data from the data file.""" self._init() - self._collector.reset() - self._data_files.read(self._data) + if self._collector: + self._collector.reset() + self._init_data(suffix=None) + self._post_init() + self._data.read() + + def _init_for_start(self): + """Initialization for start()""" + concurrency = self.config.concurrency or [] + if "multiprocessing" in concurrency: + if not patch_multiprocessing: + raise CoverageException( # pragma: only jython + "multiprocessing is not supported on this Python" + ) + patch_multiprocessing(rcfile=self.config.config_file) + # Multi-processing uses parallel for the subprocesses, so also use + # it for the main process. + self.config.parallel = True + + self._collector = Collector( + should_trace=self._should_trace, + check_include=self._check_include_omit_etc, + timid=self.config.timid, + branch=self.config.branch, + warn=self._warn, + concurrency=concurrency, + ) + + suffix = self._data_suffix_specified + if suffix or self.config.parallel: + if not isinstance(suffix, string_class): + # if data_suffix=True, use .machinename.pid.random + suffix = True + else: + suffix = None + + self._init_data(suffix) + + # Early warning if we aren't going to be able to support plugins. + if self._plugins.file_tracers and not self._collector.supports_plugins: + self._warn( + "Plugin file tracers (%s) aren't supported with %s" % ( + ", ".join( + plugin._coverage_plugin_name + for plugin in self._plugins.file_tracers + ), + self._collector.tracer_name(), + ) + ) + for plugin in self._plugins.file_tracers: + plugin._coverage_enabled = False + + # Create the file classifying substructure. + self._inorout = self._inorout_class(warn=self._warn) + self._inorout.configure(self.config) + self._inorout.plugins = self._plugins + self._inorout.disp_class = self._collector.file_disposition_class + + atexit.register(self._atexit) + + def _init_data(self, suffix): + """Create a data file if we don't have one yet.""" + if self._data is None: + # Create the data file. We do this at construction time so that the + # data file will be written into the directory where the process + # started rather than wherever the process eventually chdir'd to. + self._data = CoverageData( + basename=self.config.data_file, + suffix=suffix, + warn=self._warn, + debug=self._debug, + ) def start(self): """Start measuring code coverage. @@ -403,19 +413,22 @@ class Coverage(object): """ self._init() - self._inorout.warn_conflicting_settings() + if not self._inited_for_start: + self._inited_for_start = True + self._init_for_start() + self._post_init() - if self._run_suffix: - # Calling start() means we're running code, so use the run_suffix - # as the data_suffix when we eventually save the data. - self._data_suffix = self._run_suffix - if self._auto_load: - self.load() + # Issue warnings for possible problems. + self._inorout.warn_conflicting_settings() - # See if we think some code that would eventually be measured has already been imported. + # See if we think some code that would eventually be measured has + # already been imported. if self._warn_preimported_source: self._inorout.warn_already_imported_files() + if self._auto_load: + self.load() + self._collector.start() self._started = True @@ -442,9 +455,12 @@ class Coverage(object): """ self._init() - self._collector.reset() - self._data.erase() - self._data_files.erase(parallel=self.config.parallel) + self._post_init() + if self._collector: + self._collector.reset() + self._init_data(suffix=None) + self._data.erase(parallel=self.config.parallel) + self._data = None def clear_exclude(self, which='exclude'): """Clear the exclude list.""" @@ -495,9 +511,8 @@ class Coverage(object): def save(self): """Save the collected coverage data to the data file.""" - self._init() data = self.get_data() - self._data_files.write(data, suffix=self._data_suffix) + data.write() def combine(self, data_paths=None, strict=False): """Combine together a number of similarly-named coverage data files. @@ -522,6 +537,8 @@ class Coverage(object): """ self._init() + self._init_data(suffix=None) + self._post_init() self.get_data() aliases = None @@ -532,9 +549,7 @@ class Coverage(object): for pattern in paths[1:]: aliases.add(pattern, result) - self._data_files.combine_parallel_data( - self._data, aliases=aliases, data_paths=data_paths, strict=strict, - ) + combine_parallel_data(self._data, aliases=aliases, data_paths=data_paths, strict=strict) def get_data(self): """Get the collected data. @@ -547,8 +562,10 @@ class Coverage(object): """ self._init() + self._init_data(suffix=None) + self._post_init() - if self._collector.save_data(self._data): + if self._collector and self._collector.save_data(self._data): self._post_save_work() return self._data @@ -599,7 +616,6 @@ class Coverage(object): coverage data. """ - self._init() analysis = self._analyze(morf) return ( analysis.filename, @@ -615,6 +631,11 @@ class Coverage(object): Returns an `Analysis` object. """ + # All reporting comes through here, so do reporting initialization. + self._init() + Numbers.set_precision(self.config.precision) + self._post_init() + data = self.get_data() if not isinstance(it, FileReporter): it = self._get_file_reporter(it) @@ -801,6 +822,7 @@ class Coverage(object): import coverage as covmod self._init() + self._post_init() def plugin_info(plugins): """Make an entry for the sys_info from a list of plug-ins.""" @@ -815,13 +837,13 @@ class Coverage(object): info = [ ('version', covmod.__version__), ('coverage', covmod.__file__), - ('tracer', self._collector.tracer_name()), + ('tracer', self._collector.tracer_name() if self._collector else "-none-"), ('plugins.file_tracers', plugin_info(self._plugins.file_tracers)), ('plugins.configurers', plugin_info(self._plugins.configurers)), ('configs_attempted', self.config.attempted_config_files), ('configs_read', self.config.config_files_read), ('config_file', self.config.config_file), - ('data_path', self._data_files.filename), + ('data_path', self._data.filename if self._data else "-none-"), ('python', sys.version.replace('\n', '')), ('platform', platform.platform()), ('implementation', platform.python_implementation()), @@ -836,7 +858,8 @@ class Coverage(object): ('command_line', " ".join(getattr(sys, 'argv', ['???']))), ] - info.extend(self._inorout.sys_info()) + if self._inorout: + info.extend(self._inorout.sys_info()) return info diff --git a/coverage/data.py b/coverage/data.py index 9f2d1308..f03e90ca 100644 --- a/coverage/data.py +++ b/coverage/data.py @@ -15,14 +15,24 @@ import socket from coverage import env from coverage.backward import iitems, string_class -from coverage.debug import _TEST_NAME_FILE from coverage.files import PathAliases from coverage.misc import CoverageException, file_be_gone, isolate_module os = isolate_module(os) -class CoverageData(object): +def filename_suffix(suffix): + if suffix is True: + # If data_suffix was a simple true value, then make a suffix with + # plenty of distinguishing information. We do this here in + # `save()` at the last minute so that the pid will be correct even + # if the process forks. + dice = random.Random(os.urandom(8)).randint(0, 999999) + suffix = "%s.%s.%06d" % (socket.gethostname(), os.getpid(), dice) + return suffix + + +class CoverageJsonData(object): """Manages collected coverage data, including file storage. This class is the public supported API to the data coverage.py collects @@ -57,8 +67,10 @@ class CoverageData(object): names in this API are case-sensitive, even on platforms with case-insensitive file systems. - To read a coverage.py data file, use :meth:`read_file`, or - :meth:`read_fileobj` if you have an already-opened file. You can then + A data file is associated with the data when the :class:`CoverageData` + is created. + + To read a coverage.py data file, use :meth:`read`. You can then access the line, arc, or file tracer data with :meth:`lines`, :meth:`arcs`, or :meth:`file_tracer`. Run information is available with :meth:`run_infos`. @@ -69,17 +81,15 @@ class CoverageData(object): most Python containers, you can determine if there is any data at all by using this object as a boolean value. - Most data files will be created by coverage.py itself, but you can use methods here to create data files if you like. The :meth:`add_lines`, :meth:`add_arcs`, and :meth:`add_file_tracers` methods add data, in ways that are convenient for coverage.py. The :meth:`add_run_info` method adds key-value pairs to the run information. - To add a file without any measured data, use :meth:`touch_file`. + To add a source file without any measured data, use :meth:`touch_file`. - You write to a named file with :meth:`write_file`, or to an already opened - file with :meth:`write_fileobj`. + Write the data to its file with :meth:`write`. You can clear the data in memory with :meth:`erase`. Two data collections can be combined by using :meth:`update` on one :class:`CoverageData`, @@ -112,13 +122,20 @@ class CoverageData(object): # line data is easily recovered from the arcs: it is all the first elements # of the pairs that are greater than zero. - def __init__(self, debug=None): + def __init__(self, basename=None, suffix=None, warn=None, debug=None): """Create a CoverageData. + `warn` is the warning function to use. + + `basename` is the name of the file to use for storing data. + `debug` is a `DebugControl` object for writing debug messages. """ + self._warn = warn self._debug = debug + self.filename = os.path.abspath(basename or ".coverage") + self.suffix = suffix # A map from canonical Python source file name to a dictionary in # which there's an entry for each line number that has been @@ -238,31 +255,21 @@ class CoverageData(object): """A list of all files that had been measured.""" return list(self._arcs or self._lines or {}) - def line_counts(self, fullpath=False): - """Return a dict summarizing the line coverage data. - - Keys are based on the file names, and values are the number of executed - lines. If `fullpath` is true, then the keys are the full pathnames of - the files, otherwise they are the basenames of the files. - - Returns a dict mapping file names to counts of lines. - - """ - summ = {} - if fullpath: - filename_fn = lambda f: f - else: - filename_fn = os.path.basename - for filename in self.measured_files(): - summ[filename_fn(filename)] = len(self.lines(filename)) - return summ - def __nonzero__(self): return bool(self._lines or self._arcs) __bool__ = __nonzero__ - def read_fileobj(self, file_obj): + def read(self): + """Read the coverage data. + + It is fine for the file to not exist, in which case no data is read. + + """ + if os.path.exists(self.filename): + self._read_file(self.filename) + + def _read_fileobj(self, file_obj): """Read the coverage data from the given file object. Should only be used on an empty CoverageData object. @@ -284,13 +291,13 @@ class CoverageData(object): self._validate() - def read_file(self, filename): + def _read_file(self, filename): """Read the coverage data from `filename` into this object.""" if self._debug and self._debug.should('dataio'): self._debug.write("Reading data from %r" % (filename,)) try: with self._open_for_reading(filename) as f: - self.read_fileobj(f) + self._read_fileobj(f) except Exception as exc: raise CoverageException( "Couldn't read data from '%s': %s: %s" % ( @@ -438,7 +445,22 @@ class CoverageData(object): self._validate() - def write_fileobj(self, file_obj): + def write(self): + """Write the collected coverage data to a file. + + `suffix` is a suffix to append to the base file name. This can be used + for multiple or parallel execution, so that many coverage data files + can exist simultaneously. A dot will be used to join the base name and + the suffix. + + """ + filename = self.filename + suffix = filename_suffix(self.suffix) + if suffix: + filename += "." + suffix + self._write_file(filename) + + def _write_fileobj(self, file_obj): """Write the coverage data to `file_obj`.""" # Create the file data. @@ -460,21 +482,38 @@ class CoverageData(object): file_obj.write(self._GO_AWAY) json.dump(file_data, file_obj, separators=(',', ':')) - def write_file(self, filename): + def _write_file(self, filename): """Write the coverage data to `filename`.""" if self._debug and self._debug.should('dataio'): self._debug.write("Writing data to %r" % (filename,)) with open(filename, 'w') as fdata: - self.write_fileobj(fdata) + self._write_fileobj(fdata) - def erase(self): - """Erase the data in this object.""" + def erase(self, parallel=False): + """Erase the data in this object. + + If `parallel` is true, then also deletes data files created from the + basename by parallel-mode. + + """ self._lines = None self._arcs = None self._file_tracers = {} self._runs = [] self._validate() + if self._debug and self._debug.should('dataio'): + self._debug.write("Erasing data file %r" % (self.filename,)) + file_be_gone(self.filename) + if parallel: + data_dir, local = os.path.split(self.filename) + localdot = local + '.*' + pattern = os.path.join(os.path.abspath(data_dir), localdot) + for filename in glob.glob(pattern): + if self._debug and self._debug.should('dataio'): + self._debug.write("Erasing parallel data file %r" % (filename,)) + file_be_gone(filename) + def update(self, other_data, aliases=None): """Update this data with data from another `CoverageData`. @@ -582,20 +621,6 @@ class CoverageData(object): for key in val: assert isinstance(key, string_class), "Key in _runs shouldn't be %r" % (key,) - def add_to_hash(self, filename, hasher): - """Contribute `filename`'s data to the `hasher`. - - `hasher` is a `coverage.misc.Hasher` instance to be updated with - the file's data. It should only get the results data, not the run - data. - - """ - if self._has_arcs(): - hasher.update(sorted(self.arcs(filename) or [])) - else: - hasher.update(sorted(self.lines(filename) or [])) - hasher.update(self.file_tracer(filename)) - ## ## Internal ## @@ -609,139 +634,111 @@ class CoverageData(object): return self._arcs is not None -class CoverageDataFiles(object): - """Manage the use of coverage data files.""" +STORAGE = os.environ.get("COVERAGE_STORAGE", "sql") +if STORAGE == "json": + CoverageData = CoverageJsonData +elif STORAGE == "sql": + from coverage.sqldata import CoverageSqliteData + CoverageData = CoverageSqliteData - def __init__(self, basename=None, warn=None, debug=None): - """Create a CoverageDataFiles to manage data files. - `warn` is the warning function to use. +def line_counts(data, fullpath=False): + """Return a dict summarizing the line coverage data. - `basename` is the name of the file to use for storing data. + Keys are based on the file names, and values are the number of executed + lines. If `fullpath` is true, then the keys are the full pathnames of + the files, otherwise they are the basenames of the files. - `debug` is a `DebugControl` object for writing debug messages. + Returns a dict mapping file names to counts of lines. - """ - self.warn = warn - self.debug = debug + """ + summ = {} + if fullpath: + filename_fn = lambda f: f + else: + filename_fn = os.path.basename + for filename in data.measured_files(): + summ[filename_fn(filename)] = len(data.lines(filename)) + return summ - # Construct the file name that will be used for data storage. - self.filename = os.path.abspath(basename or ".coverage") - def erase(self, parallel=False): - """Erase the data from the file storage. +def add_data_to_hash(data, filename, hasher): + """Contribute `filename`'s data to the `hasher`. - If `parallel` is true, then also deletes data files created from the - basename by parallel-mode. + `hasher` is a `coverage.misc.Hasher` instance to be updated with + the file's data. It should only get the results data, not the run + data. - """ - if self.debug and self.debug.should('dataio'): - self.debug.write("Erasing data file %r" % (self.filename,)) - file_be_gone(self.filename) - if parallel: - data_dir, local = os.path.split(self.filename) - localdot = local + '.*' - pattern = os.path.join(os.path.abspath(data_dir), localdot) - for filename in glob.glob(pattern): - if self.debug and self.debug.should('dataio'): - self.debug.write("Erasing parallel data file %r" % (filename,)) - file_be_gone(filename) - - def read(self, data): - """Read the coverage data.""" - if os.path.exists(self.filename): - data.read_file(self.filename) - - def write(self, data, suffix=None): - """Write the collected coverage data to a file. - - `suffix` is a suffix to append to the base file name. This can be used - for multiple or parallel execution, so that many coverage data files - can exist simultaneously. A dot will be used to join the base name and - the suffix. + """ + if data.has_arcs(): + hasher.update(sorted(data.arcs(filename) or [])) + else: + hasher.update(sorted(data.lines(filename) or [])) + hasher.update(data.file_tracer(filename)) - """ - filename = self.filename - if suffix is True: - # If data_suffix was a simple true value, then make a suffix with - # plenty of distinguishing information. We do this here in - # `save()` at the last minute so that the pid will be correct even - # if the process forks. - extra = "" - if _TEST_NAME_FILE: # pragma: debugging - with open(_TEST_NAME_FILE) as f: - test_name = f.read() - extra = "." + test_name - dice = random.Random(os.urandom(8)).randint(0, 999999) - suffix = "%s%s.%s.%06d" % (socket.gethostname(), extra, os.getpid(), dice) - if suffix: - filename += "." + suffix - data.write_file(filename) +def combine_parallel_data(data, aliases=None, data_paths=None, strict=False): + """Combine a number of data files together. - def combine_parallel_data(self, data, aliases=None, data_paths=None, strict=False): - """Combine a number of data files together. + Treat `data.filename` as a file prefix, and combine the data from all + of the data files starting with that prefix plus a dot. - Treat `self.filename` as a file prefix, and combine the data from all - of the data files starting with that prefix plus a dot. + If `aliases` is provided, it's a `PathAliases` object that is used to + re-map paths to match the local machine's. - If `aliases` is provided, it's a `PathAliases` object that is used to - re-map paths to match the local machine's. + If `data_paths` is provided, it is a list of directories or files to + combine. Directories are searched for files that start with + `data.filename` plus dot as a prefix, and those files are combined. - If `data_paths` is provided, it is a list of directories or files to - combine. Directories are searched for files that start with - `self.filename` plus dot as a prefix, and those files are combined. + If `data_paths` is not provided, then the directory portion of + `data.filename` is used as the directory to search for data files. - If `data_paths` is not provided, then the directory portion of - `self.filename` is used as the directory to search for data files. + Every data file found and combined is then deleted from disk. If a file + cannot be read, a warning will be issued, and the file will not be + deleted. - Every data file found and combined is then deleted from disk. If a file - cannot be read, a warning will be issued, and the file will not be - deleted. + If `strict` is true, and no files are found to combine, an error is + raised. - If `strict` is true, and no files are found to combine, an error is - raised. + """ + # Because of the os.path.abspath in the constructor, data_dir will + # never be an empty string. + data_dir, local = os.path.split(data.filename) + localdot = local + '.*' + + data_paths = data_paths or [data_dir] + files_to_combine = [] + for p in data_paths: + if os.path.isfile(p): + files_to_combine.append(os.path.abspath(p)) + elif os.path.isdir(p): + pattern = os.path.join(os.path.abspath(p), localdot) + files_to_combine.extend(glob.glob(pattern)) + else: + raise CoverageException("Couldn't combine from non-existent path '%s'" % (p,)) - """ - # Because of the os.path.abspath in the constructor, data_dir will - # never be an empty string. - data_dir, local = os.path.split(self.filename) - localdot = local + '.*' - - data_paths = data_paths or [data_dir] - files_to_combine = [] - for p in data_paths: - if os.path.isfile(p): - files_to_combine.append(os.path.abspath(p)) - elif os.path.isdir(p): - pattern = os.path.join(os.path.abspath(p), localdot) - files_to_combine.extend(glob.glob(pattern)) - else: - raise CoverageException("Couldn't combine from non-existent path '%s'" % (p,)) - - if strict and not files_to_combine: - raise CoverageException("No data to combine") - - files_combined = 0 - for f in files_to_combine: - new_data = CoverageData(debug=self.debug) - try: - new_data.read_file(f) - except CoverageException as exc: - if self.warn: - # The CoverageException has the file name in it, so just - # use the message as the warning. - self.warn(str(exc)) - else: - data.update(new_data, aliases=aliases) - files_combined += 1 - if self.debug and self.debug.should('dataio'): - self.debug.write("Deleting combined data file %r" % (f,)) - file_be_gone(f) - - if strict and not files_combined: - raise CoverageException("No usable data files") + if strict and not files_to_combine: + raise CoverageException("No data to combine") + files_combined = 0 + for f in files_to_combine: + try: + new_data = CoverageData(f, debug=data._debug) + new_data.read() + except CoverageException as exc: + if data._warn: + # The CoverageException has the file name in it, so just + # use the message as the warning. + data._warn(str(exc)) + else: + data.update(new_data, aliases=aliases) + files_combined += 1 + if data._debug and data._debug.should('dataio'): + data._debug.write("Deleting combined data file %r" % (f,)) + file_be_gone(f) + + if strict and not files_combined: + raise CoverageException("No usable data files") def canonicalize_json_data(data): """Canonicalize our JSON data so it can be compared.""" diff --git a/coverage/debug.py b/coverage/debug.py index d63a9070..f491a0f7 100644 --- a/coverage/debug.py +++ b/coverage/debug.py @@ -24,13 +24,12 @@ os = isolate_module(os) # This is a list of forced debugging options. FORCED_DEBUG = [] -# A hack for debugging testing in sub-processes. -_TEST_NAME_FILE = "" # "/tmp/covtest.txt" - class DebugControl(object): """Control and output for debugging.""" + show_repr_attr = False # For SimpleRepr + def __init__(self, options, output): """Configure the options and output file for debugging.""" self.options = list(options) + FORCED_DEBUG @@ -71,6 +70,10 @@ class DebugControl(object): `msg` is the line to write. A newline will be appended. """ + if self.should('self'): + caller_self = inspect.stack()[1][0].f_locals.get('self') + if caller_self is not None: + msg = "[self: {!r}] {}".format(caller_self, msg) self.output.write(msg+"\n") if self.should('callers'): dump_stack_frames(out=self.output, skip=1) @@ -167,6 +170,17 @@ def add_pid_and_tid(text): return text +class SimpleRepr(object): + """A mixin implementing a simple __repr__.""" + def __repr__(self): + show_attrs = ((k, v) for k, v in self.__dict__.items() if getattr(v, "show_repr_attr", True)) + return "<{klass} @0x{id:x} {attrs}>".format( + klass=self.__class__.__name__, + id=id(self), + attrs=" ".join("{}={!r}".format(k, v) for k, v in show_attrs), + ) + + def filter_text(text, filters): """Run `text` through a series of filters. diff --git a/coverage/html.py b/coverage/html.py index 186e9d22..bb519254 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -12,6 +12,7 @@ import shutil import coverage from coverage import env from coverage.backward import iitems +from coverage.data import add_data_to_hash from coverage.files import flat_rootname from coverage.misc import CoverageException, file_be_gone, Hasher, isolate_module from coverage.report import Reporter @@ -67,7 +68,7 @@ def read_data(fname): def write_html(fname, html): """Write `html` to `fname`, properly encoded.""" - html = re.sub(r"(\A\s+)|(\s+$)", "", html, flags=re.MULTILINE) + html = re.sub(r"(\A\s+)|(\s+$)", "", html, flags=re.MULTILINE) + "\n" with open(fname, "wb") as fout: fout.write(html.encode('ascii', 'xmlcharrefreplace')) @@ -169,7 +170,7 @@ class HtmlReporter(Reporter): """Compute a hash that changes if the file needs to be re-reported.""" m = Hasher() m.update(source) - self.data.add_to_hash(fr.filename, m) + add_data_to_hash(self.data, fr.filename, m) return m.hexdigest() def html_file(self, fr, analysis): diff --git a/coverage/misc.py b/coverage/misc.py index 50c8d8ac..ab950846 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -250,16 +250,6 @@ def _needs_to_implement(that, func_name): ) -class SimpleRepr(object): - """A mixin implementing a simple __repr__.""" - def __repr__(self): - return "<{klass} @{id:x} {attrs}>".format( - klass=self.__class__.__name__, - id=id(self) & 0xFFFFFF, - attrs=" ".join("{}={!r}".format(k, v) for k, v in self.__dict__.items()), - ) - - class BaseCoverageException(Exception): """The base of all Coverage exceptions.""" pass diff --git a/coverage/results.py b/coverage/results.py index 7e3bd268..fb919c9b 100644 --- a/coverage/results.py +++ b/coverage/results.py @@ -6,7 +6,8 @@ import collections from coverage.backward import iitems -from coverage.misc import contract, format_lines, SimpleRepr +from coverage.debug import SimpleRepr +from coverage.misc import contract, format_lines class Analysis(object): diff --git a/coverage/sqldata.py b/coverage/sqldata.py new file mode 100644 index 00000000..f92e245b --- /dev/null +++ b/coverage/sqldata.py @@ -0,0 +1,435 @@ +# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 +# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt + +"""Sqlite coverage data.""" + +# TODO: get sys_info for data class, so we can see sqlite version etc +# TODO: get rid of skip_unless_data_storage_is_json +# TODO: get rid of "JSON message" and "SQL message" in the tests +# TODO: check the schema +# TODO: get rid of the application_id? +# TODO: factor out dataop debugging to a wrapper class? +# TODO: make sure all dataop debugging is in place somehow +# TODO: should writes be batched? +# TODO: settle the os.fork question +# TODO: run_info + +import glob +import os +import sqlite3 +import struct + +from coverage.backward import iitems +from coverage.data import filename_suffix +from coverage.debug import SimpleRepr +from coverage.files import PathAliases +from coverage.misc import CoverageException, file_be_gone + + +SCHEMA = """ +create table schema ( + version integer +); + +insert into schema (version) values (1); + +create table meta ( + has_lines boolean, + has_arcs boolean +); + +create table file ( + id integer primary key, + path text, + unique(path) +); + +create table line ( + file_id integer, + lineno integer, + unique(file_id, lineno) +); + +create table arc ( + file_id integer, + fromno integer, + tono integer, + unique(file_id, fromno, tono) +); + +create table tracer ( + file_id integer primary key, + tracer text +); +""" + +APP_ID = 0xc07e8a6e # "coverage", kind of. + +def unsigned_to_signed(val): + return struct.unpack('>i', struct.pack('>I', val))[0] + +def signed_to_unsigned(val): + return struct.unpack('>I', struct.pack('>i', val))[0] + +class CoverageSqliteData(SimpleRepr): + def __init__(self, basename=None, suffix=None, warn=None, debug=None): + self.filename = os.path.abspath(basename or ".coverage") + suffix = filename_suffix(suffix) + if suffix: + self.filename += "." + suffix + self._warn = warn + self._debug = debug + + self._file_map = {} + self._db = None + # Are we in sync with the data file? + self._have_used = False + + self._has_lines = False + self._has_arcs = False + + def _reset(self): + self._file_map = {} + if self._db is not None: + self._db.close() + self._db = None + self._have_used = False + + def _create_db(self): + if self._debug and self._debug.should('dataio'): + self._debug.write("Creating data file {!r}".format(self.filename)) + self._db = Sqlite(self.filename, self._debug) + with self._db: + self._db.execute("pragma application_id = {}".format(unsigned_to_signed(APP_ID))) + for stmt in SCHEMA.split(';'): + stmt = stmt.strip() + if stmt: + self._db.execute(stmt) + self._db.execute( + "insert into meta (has_lines, has_arcs) values (?, ?)", + (self._has_lines, self._has_arcs) + ) + + def _open_db(self): + if self._debug and self._debug.should('dataio'): + self._debug.write("Opening data file {!r}".format(self.filename)) + self._db = Sqlite(self.filename, self._debug) + with self._db: + for app_id, in self._db.execute("pragma application_id"): + app_id = signed_to_unsigned(int(app_id)) + if app_id != APP_ID: + raise CoverageException( + "Couldn't use {!r}: wrong application_id: " + "0x{:08x} != 0x{:08x}".format(self.filename, app_id, APP_ID) + ) + for row in self._db.execute("select has_lines, has_arcs from meta"): + self._has_lines, self._has_arcs = row + + for path, id in self._db.execute("select path, id from file"): + self._file_map[path] = id + + def _connect(self): + if self._db is None: + if os.path.exists(self.filename): + self._open_db() + else: + self._create_db() + return self._db + + def __nonzero__(self): + try: + with self._connect() as con: + rows = con.execute("select * from file limit 1") + return bool(list(rows)) + except CoverageException: + return False + + __bool__ = __nonzero__ + + def _file_id(self, filename, add=False): + """Get the file id for `filename`. + + If filename is not in the database yet, add if it `add` is True. + If `add` is not True, return None. + """ + if filename not in self._file_map: + if add: + with self._connect() as con: + cur = con.execute("insert into file (path) values (?)", (filename,)) + self._file_map[filename] = cur.lastrowid + return self._file_map.get(filename) + + def add_lines(self, line_data): + """Add measured line data. + + `line_data` is a dictionary mapping file names to dictionaries:: + + { filename: { lineno: None, ... }, ...} + + """ + if self._debug and self._debug.should('dataop'): + self._debug.write("Adding lines: %d files, %d lines total" % ( + len(line_data), sum(len(lines) for lines in line_data.values()) + )) + self._start_using() + self._choose_lines_or_arcs(lines=True) + with self._connect() as con: + for filename, linenos in iitems(line_data): + file_id = self._file_id(filename, add=True) + data = [(file_id, lineno) for lineno in linenos] + con.executemany( + "insert or ignore into line (file_id, lineno) values (?, ?)", + data, + ) + + def add_arcs(self, arc_data): + """Add measured arc data. + + `arc_data` is a dictionary mapping file names to dictionaries:: + + { filename: { (l1,l2): None, ... }, ...} + + """ + if self._debug and self._debug.should('dataop'): + self._debug.write("Adding arcs: %d files, %d arcs total" % ( + len(arc_data), sum(len(arcs) for arcs in arc_data.values()) + )) + self._start_using() + self._choose_lines_or_arcs(arcs=True) + with self._connect() as con: + for filename, arcs in iitems(arc_data): + file_id = self._file_id(filename, add=True) + data = [(file_id, fromno, tono) for fromno, tono in arcs] + con.executemany( + "insert or ignore into arc (file_id, fromno, tono) values (?, ?, ?)", + data, + ) + + def _choose_lines_or_arcs(self, lines=False, arcs=False): + if lines and self._has_arcs: + raise CoverageException("Can't add lines to existing arc data") + if arcs and self._has_lines: + raise CoverageException("Can't add arcs to existing line data") + if not self._has_arcs and not self._has_lines: + self._has_lines = lines + self._has_arcs = arcs + with self._connect() as con: + con.execute("update meta set has_lines = ?, has_arcs = ?", (lines, arcs)) + + def add_file_tracers(self, file_tracers): + """Add per-file plugin information. + + `file_tracers` is { filename: plugin_name, ... } + + """ + self._start_using() + with self._connect() as con: + for filename, plugin_name in iitems(file_tracers): + file_id = self._file_id(filename) + if file_id is None: + raise CoverageException( + "Can't add file tracer data for unmeasured file '%s'" % (filename,) + ) + + existing_plugin = self.file_tracer(filename) + if existing_plugin: + if existing_plugin != plugin_name: + raise CoverageException( + "Conflicting file tracer name for '%s': %r vs %r" % ( + filename, existing_plugin, plugin_name, + ) + ) + elif plugin_name: + con.execute( + "insert into tracer (file_id, tracer) values (?, ?)", + (file_id, plugin_name) + ) + + def touch_file(self, filename, plugin_name=""): + """Ensure that `filename` appears in the data, empty if needed. + + `plugin_name` is the name of the plugin resposible for this file. It is used + to associate the right filereporter, etc. + """ + self._start_using() + if self._debug and self._debug.should('dataop'): + self._debug.write("Touching %r" % (filename,)) + if not self._has_arcs and not self._has_lines: + raise CoverageException("Can't touch files in an empty CoverageSqliteData") + + self._file_id(filename, add=True) + if plugin_name: + # Set the tracer for this file + self.add_file_tracers({filename: plugin_name}) + + def update(self, other_data, aliases=None): + if self._has_lines and other_data._has_arcs: + raise CoverageException("Can't combine arc data with line data") + if self._has_arcs and other_data._has_lines: + raise CoverageException("Can't combine line data with arc data") + + aliases = aliases or PathAliases() + + # See what we had already measured, for accurate conflict reporting. + this_measured = set(self.measured_files()) + + # lines + if other_data._has_lines: + for filename in other_data.measured_files(): + lines = set(other_data.lines(filename)) + filename = aliases.map(filename) + lines.update(self.lines(filename) or ()) + self.add_lines({filename: lines}) + + # arcs + if other_data._has_arcs: + for filename in other_data.measured_files(): + arcs = set(other_data.arcs(filename)) + filename = aliases.map(filename) + arcs.update(self.arcs(filename) or ()) + self.add_arcs({filename: arcs}) + + # file_tracers + for filename in other_data.measured_files(): + other_plugin = other_data.file_tracer(filename) + filename = aliases.map(filename) + if filename in this_measured: + this_plugin = self.file_tracer(filename) + else: + this_plugin = None + if this_plugin is None: + self.add_file_tracers({filename: other_plugin}) + elif this_plugin != other_plugin: + raise CoverageException( + "Conflicting file tracer name for '%s': %r vs %r" % ( + filename, this_plugin, other_plugin, + ) + ) + + def erase(self, parallel=False): + """Erase the data in this object. + + If `parallel` is true, then also deletes data files created from the + basename by parallel-mode. + + """ + self._reset() + if self._debug and self._debug.should('dataio'): + self._debug.write("Erasing data file {!r}".format(self.filename)) + file_be_gone(self.filename) + if parallel: + data_dir, local = os.path.split(self.filename) + localdot = local + '.*' + pattern = os.path.join(os.path.abspath(data_dir), localdot) + for filename in glob.glob(pattern): + if self._debug and self._debug.should('dataio'): + self._debug.write("Erasing parallel data file {!r}".format(filename)) + file_be_gone(filename) + + def read(self): + self._connect() # TODO: doesn't look right + self._have_used = True + + def write(self): + """Write the collected coverage data to a file.""" + pass + + def _start_using(self): + if not self._have_used: + self.erase() + self._have_used = True + + def has_arcs(self): + return bool(self._has_arcs) + + def measured_files(self): + """A list of all files that had been measured.""" + return list(self._file_map) + + def file_tracer(self, filename): + """Get the plugin name of the file tracer for a file. + + Returns the name of the plugin that handles this file. If the file was + measured, but didn't use a plugin, then "" is returned. If the file + was not measured, then None is returned. + + """ + self._start_using() + with self._connect() as con: + file_id = self._file_id(filename) + if file_id is None: + return None + row = con.execute("select tracer from tracer where file_id = ?", (file_id,)).fetchone() + if row is not None: + return row[0] or "" + return "" # File was measured, but no tracer associated. + + def lines(self, filename): + self._start_using() + if self.has_arcs(): + arcs = self.arcs(filename) + if arcs is not None: + import itertools + all_lines = itertools.chain.from_iterable(arcs) + return list(set(l for l in all_lines if l > 0)) + + with self._connect() as con: + file_id = self._file_id(filename) + if file_id is None: + return None + else: + linenos = con.execute("select lineno from line where file_id = ?", (file_id,)) + return [lineno for lineno, in linenos] + + def arcs(self, filename): + self._start_using() + with self._connect() as con: + file_id = self._file_id(filename) + if file_id is None: + return None + else: + arcs = con.execute("select fromno, tono from arc where file_id = ?", (file_id,)) + return [pair for pair in arcs] + + def run_infos(self): + return [] # TODO + + +class Sqlite(SimpleRepr): + def __init__(self, filename, debug): + self.debug = debug if (debug and debug.should('sql')) else None + if self.debug: + self.debug.write("Connecting to {!r}".format(filename)) + self.filename = filename + self.con = sqlite3.connect(self.filename) + + # This pragma makes writing faster. It disables rollbacks, but we never need them. + # PyPy needs the .close() calls here, or sqlite gets twisted up: + # https://bitbucket.org/pypy/pypy/issues/2872/default-isolation-mode-is-different-on + self.execute("pragma journal_mode=off").close() + # This pragma makes writing faster. + self.execute("pragma synchronous=off").close() + + def close(self): + self.con.close() + + def __enter__(self): + self.con.__enter__() + return self + + def __exit__(self, exc_type, exc_value, traceback): + return self.con.__exit__(exc_type, exc_value, traceback) + + def execute(self, sql, parameters=()): + if self.debug: + tail = " with {!r}".format(parameters) if parameters else "" + self.debug.write("Executing {!r}{}".format(sql, tail)) + try: + return self.con.execute(sql, parameters) + except sqlite3.Error as exc: + raise CoverageException("Couldn't use data file {!r}: {}".format(self.filename, exc)) + + def executemany(self, sql, data): + if self.debug: + self.debug.write("Executing many {!r} with {} rows".format(sql, len(data))) + return self.con.executemany(sql, data) diff --git a/doc/cmd.rst b/doc/cmd.rst index d198178f..908b2ee9 100644 --- a/doc/cmd.rst +++ b/doc/cmd.rst @@ -486,6 +486,8 @@ to log: * ``process``: show process creation information, and changes in the current directory. +* ``self``: annotate each debug message with the object printing the message. + * ``sys``: before starting, dump all the system and environment information, as with :ref:`coverage debug sys <cmd_debug>`. diff --git a/doc/contributing.rst b/doc/contributing.rst index 71fa6937..90d73097 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -122,13 +122,14 @@ To limit tox to just a few versions of Python, use the ``-e`` switch:: To run just a few tests, you can use `pytest test selectors`_:: $ tox tests/test_misc.py - $ tox tests/test_misc.py::SetupPyTest - $ tox tests/test_misc.py::SetupPyTest::test_metadata + $ tox tests/test_misc.py::HasherTest + $ tox tests/test_misc.py::HasherTest::test_string_hashing These command run the tests in one file, one class, and just one test, respectively. -You can also affect the test runs with environment variables: +You can also affect the test runs with environment variables. Define any of +these as 1 to use them: - COVERAGE_NO_PYTRACER disables the Python tracer if you only want to run the CTracer tests. @@ -139,8 +140,9 @@ You can also affect the test runs with environment variables: - COVEGE_AST_DUMP will dump the AST tree as it is being used during code parsing. -- COVERAGE_KEEP_OUTPUT will save the output files that were generated by the - gold-file tests, ones that compare output files to saved gold files. +- COVERAGE_KEEP_TMP keeps the temporary directories in which tests are run. + This makes debugging tests easier. The temporary directories are at + ``$TMPDIR/coverage_test/*``, and are named for the test that made them. Of course, run all the tests on every version of Python you have, before @@ -287,7 +287,6 @@ def do_check_eol(): check_files("coverage", ["*.py"]) check_files("coverage/ctracer", ["*.c", "*.h"]) check_files("coverage/htmlfiles", ["*.html", "*.css", "*.js"]) - check_file("tests/farm/html/src/bom.py", crlf=False) check_files("tests", ["*.py"]) check_files("tests", ["*,cover"], trail_white=False) check_files("tests/js", ["*.js", "*.html"]) diff --git a/lab/gendata.py b/lab/gendata.py new file mode 100644 index 00000000..27ad4fda --- /dev/null +++ b/lab/gendata.py @@ -0,0 +1,42 @@ +# Run some timing tests of JsonData vs SqliteData. + +import random +import time + +from coverage.data import CoverageJsonData +from coverage.sqldata import CoverageSqliteData + +NUM_FILES = 1000 +NUM_LINES = 1000 + +def gen_data(cdata): + rnd = random.Random() + rnd.seed(17) + + def linenos(num_lines, prob): + return (n for n in range(num_lines) if random.random() < prob) + + start = time.time() + for i in range(NUM_FILES): + filename = "/src/foo/project/file{i}.py".format(i=i) + line_data = { filename: dict.fromkeys(linenos(NUM_LINES, .6)) } + cdata.add_lines(line_data) + + cdata.write() + end = time.time() + delta = end - start + return delta + +class DummyData: + def add_lines(self, line_data): + return + def write(self): + return + +overhead = gen_data(DummyData()) +jtime = gen_data(CoverageJsonData("gendata.json")) - overhead +stime = gen_data(CoverageSqliteData("gendata.db")) - overhead +print("Overhead: {overhead:.3f}s".format(overhead=overhead)) +print("JSON: {jtime:.3f}s".format(jtime=jtime)) +print("SQLite: {stime:.3f}s".format(stime=stime)) +print("{slower:.3f}x slower".format(slower=stime/jtime)) diff --git a/requirements/dev.pip b/requirements/dev.pip index d7ed3131..c2cfcb1b 100644 --- a/requirements/dev.pip +++ b/requirements/dev.pip @@ -12,10 +12,7 @@ pip==18.0.0 # for linting. greenlet==0.4.14 -mock==2.0.0 -PyContracts==1.8.3 pylint==1.9.2 -unittest-mixins==1.4 check-manifest==0.37 readme_renderer==21.0 diff --git a/requirements/pytest.pip b/requirements/pytest.pip index e8c59d29..139c6479 100644 --- a/requirements/pytest.pip +++ b/requirements/pytest.pip @@ -7,3 +7,9 @@ pytest==3.7.1 pluggy>=0.7 # pytest needs this, but pip doesn't understand pytest-xdist==1.22.5 flaky==3.4.0 +mock==2.0.0 +PyContracts==1.8.3 + +# Our testing mixins +unittest-mixins==1.6 +#-e/Users/ned/unittest_mixins @@ -1,5 +1,5 @@ [tool:pytest] -addopts = -q -n3 --strict --no-flaky-report -rfe +addopts = -q -n3 --strict --no-flaky-report -rfe --failed-first markers = expensive: too slow to run during "make smoke" diff --git a/tests/coveragetest.py b/tests/coveragetest.py index 94f50852..6e308718 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -24,7 +24,7 @@ from coverage import env from coverage.backunittest import TestCase, unittest from coverage.backward import StringIO, import_local_file, string_class, shlex_quote from coverage.cmdline import CoverageScript -from coverage.debug import _TEST_NAME_FILE +from coverage.data import STORAGE from coverage.misc import StopEverything from tests.helpers import run_command, SuperModuleCleaner @@ -81,6 +81,12 @@ class CoverageTest( # Let stderr go to stderr, pytest will capture it for us. show_stderr = True + # Temp dirs go to $TMPDIR/coverage_test/* + temp_dir_prefix = "coverage_test/" + + # Keep the temp directories if the env says to. + keep_temp_dir = bool(int(os.getenv("COVERAGE_KEEP_TMP", 0))) + def setUp(self): super(CoverageTest, self).setUp() @@ -91,11 +97,9 @@ class CoverageTest( self.last_command_output = None self.last_module_name = None - if _TEST_NAME_FILE: # pragma: debugging - with open(_TEST_NAME_FILE, "w") as f: - f.write("%s_%s" % ( - self.__class__.__name__, self._testMethodName, - )) + def skip_unless_data_storage_is_json(self): + if STORAGE != "json": + self.skipTest("Not using JSON for data storage") def clean_local_file_imports(self): """Clean up the results of calls to `import_local_file`. diff --git a/tests/farm/html/gold_a/a_py.html b/tests/farm/html/gold_a/a_py.html index 52c09526..119ad4a3 100644 --- a/tests/farm/html/gold_a/a_py.html +++ b/tests/farm/html/gold_a/a_py.html @@ -54,28 +54,18 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> <p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> -<p id="n7" class="pln"><a href="#n7">7</a></p> -<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> -<p id="n9" class="pln"><a href="#n9">9</a></p> -<p id="n10" class="stm mis"><a href="#n10">10</a></p> +<p id="n5" class="stm mis"><a href="#n5">5</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A test file for HTML reporting by coverage.py.</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t7" class="pln"> <span class="com"># Needed a < to look at HTML entities.</span><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> -<p id="t9" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t10" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t2" class="pln"> <span class="com"># Needed a < to look at HTML entities.</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t5" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> </td> </tr> </table> @@ -84,9 +74,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:45 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_a/index.html b/tests/farm/html/gold_a/index.html index e52d49b4..b839af1e 100644 --- a/tests/farm/html/gold_a/index.html +++ b/tests/farm/html/gold_a/index.html @@ -76,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:45 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_b_branch/b_py.html b/tests/farm/html/gold_b_branch/b_py.html index 6c3f75a8..a21175eb 100644 --- a/tests/farm/html/gold_b_branch/b_py.html +++ b/tests/farm/html/gold_b_branch/b_py.html @@ -55,72 +55,62 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> +<p id="n3" class="stm par run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> <p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> +<p id="n6" class="stm mis"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> -<p id="n8" class="stm par run hide_run"><a href="#n8">8</a></p> -<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm mis"><a href="#n11">11</a></p> -<p id="n12" class="pln"><a href="#n12">12</a></p> +<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> +<p id="n9" class="pln"><a href="#n9">9</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> +<p id="n11" class="pln"><a href="#n11">11</a></p> +<p id="n12" class="stm par run hide_run"><a href="#n12">12</a></p> <p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> <p id="n14" class="pln"><a href="#n14">14</a></p> <p id="n15" class="stm run hide_run"><a href="#n15">15</a></p> <p id="n16" class="pln"><a href="#n16">16</a></p> -<p id="n17" class="stm par run hide_run"><a href="#n17">17</a></p> +<p id="n17" class="stm run hide_run"><a href="#n17">17</a></p> <p id="n18" class="stm run hide_run"><a href="#n18">18</a></p> <p id="n19" class="pln"><a href="#n19">19</a></p> -<p id="n20" class="stm run hide_run"><a href="#n20">20</a></p> -<p id="n21" class="pln"><a href="#n21">21</a></p> -<p id="n22" class="stm run hide_run"><a href="#n22">22</a></p> -<p id="n23" class="stm run hide_run"><a href="#n23">23</a></p> -<p id="n24" class="pln"><a href="#n24">24</a></p> -<p id="n25" class="stm par run hide_run"><a href="#n25">25</a></p> -<p id="n26" class="stm mis"><a href="#n26">26</a></p> -<p id="n27" class="pln"><a href="#n27">27</a></p> -<p id="n28" class="stm mis"><a href="#n28">28</a></p> -<p id="n29" class="stm run hide_run"><a href="#n29">29</a></p> -<p id="n30" class="stm run hide_run"><a href="#n30">30</a></p> -<p id="n31" class="pln"><a href="#n31">31</a></p> -<p id="n32" class="stm run hide_run"><a href="#n32">32</a></p> +<p id="n20" class="stm par run hide_run"><a href="#n20">20</a></p> +<p id="n21" class="stm mis"><a href="#n21">21</a></p> +<p id="n22" class="pln"><a href="#n22">22</a></p> +<p id="n23" class="stm mis"><a href="#n23">23</a></p> +<p id="n24" class="stm run hide_run"><a href="#n24">24</a></p> +<p id="n25" class="stm run hide_run"><a href="#n25">25</a></p> +<p id="n26" class="pln"><a href="#n26">26</a></p> +<p id="n27" class="stm run hide_run"><a href="#n27">27</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A test file for HTML reporting by coverage.py.</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">def</span> <span class="nam">one</span><span class="op">(</span><span class="nam">x</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t7" class="pln"> <span class="com"># This will be a branch that misses the else.</span><span class="strut"> </span></p> -<p id="t8" class="stm par run hide_run"><span class="annotate short">8 ↛ 11</span><span class="annotate long">line 8 didn't jump to line 11, because the condition on line 8 was never false</span> <span class="key">if</span> <span class="nam">x</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> -<p id="t10" class="pln"> <span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t11" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> -<p id="t12" class="pln"><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="nam">one</span><span class="op">(</span><span class="num">1</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">def</span> <span class="nam">one</span><span class="op">(</span><span class="nam">x</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t2" class="pln"> <span class="com"># This will be a branch that misses the else.</span><span class="strut"> </span></p> +<p id="t3" class="stm par run hide_run"><span class="annotate short">3 ↛ 6</span><span class="annotate long">line 3 didn't jump to line 6, because the condition on line 3 was never false</span> <span class="key">if</span> <span class="nam">x</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> +<p id="t5" class="pln"> <span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t6" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> +<p id="t7" class="pln"><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="nam">one</span><span class="op">(</span><span class="num">1</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t9" class="pln"><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">def</span> <span class="nam">two</span><span class="op">(</span><span class="nam">x</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t11" class="pln"> <span class="com"># A missed else that branches to "exit"</span><span class="strut"> </span></p> +<p id="t12" class="stm par run hide_run"><span class="annotate short">12 ↛ exit</span><span class="annotate long">line 12 didn't return from function 'two', because the condition on line 12 was never false</span> <span class="key">if</span> <span class="nam">x</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t13" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> <p id="t14" class="pln"><span class="strut"> </span></p> -<p id="t15" class="stm run hide_run"><span class="key">def</span> <span class="nam">two</span><span class="op">(</span><span class="nam">x</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t16" class="pln"> <span class="com"># A missed else that branches to "exit"</span><span class="strut"> </span></p> -<p id="t17" class="stm par run hide_run"><span class="annotate short">17 ↛ exit</span><span class="annotate long">line 17 didn't return from function 'two', because the condition on line 17 was never false</span> <span class="key">if</span> <span class="nam">x</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t18" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t19" class="pln"><span class="strut"> </span></p> -<p id="t20" class="stm run hide_run"><span class="nam">two</span><span class="op">(</span><span class="num">1</span><span class="op">)</span><span class="strut"> </span></p> -<p id="t21" class="pln"><span class="strut"> </span></p> -<p id="t22" class="stm run hide_run"><span class="key">def</span> <span class="nam">three</span><span class="op">(</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t23" class="stm run hide_run"> <span class="key">try</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t24" class="pln"> <span class="com"># This if has two branches, *neither* one taken.</span><span class="strut"> </span></p> -<p id="t25" class="stm par run hide_run"><span class="annotate short">25 ↛ 26, 25 ↛ 28</span><span class="annotate long">2 missed branches: 1) line 25 didn't jump to line 26, because the condition on line 25 was never true, 2) line 25 didn't jump to line 28, because the condition on line 25 was never false</span> <span class="key">if</span> <span class="nam">name_error_this_variable_doesnt_exist</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t26" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t27" class="pln"> <span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t28" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> -<p id="t29" class="stm run hide_run"> <span class="key">except</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t30" class="stm run hide_run"> <span class="key">pass</span><span class="strut"> </span></p> -<p id="t31" class="pln"><span class="strut"> </span></p> -<p id="t32" class="stm run hide_run"><span class="nam">three</span><span class="op">(</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t15" class="stm run hide_run"><span class="nam">two</span><span class="op">(</span><span class="num">1</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t16" class="pln"><span class="strut"> </span></p> +<p id="t17" class="stm run hide_run"><span class="key">def</span> <span class="nam">three</span><span class="op">(</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t18" class="stm run hide_run"> <span class="key">try</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t19" class="pln"> <span class="com"># This if has two branches, *neither* one taken.</span><span class="strut"> </span></p> +<p id="t20" class="stm par run hide_run"><span class="annotate short">20 ↛ 21, 20 ↛ 23</span><span class="annotate long">2 missed branches: 1) line 20 didn't jump to line 21, because the condition on line 20 was never true, 2) line 20 didn't jump to line 23, because the condition on line 20 was never false</span> <span class="key">if</span> <span class="nam">name_error_this_variable_doesnt_exist</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t21" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t22" class="pln"> <span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t23" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t24" class="stm run hide_run"> <span class="key">except</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t25" class="stm run hide_run"> <span class="key">pass</span><span class="strut"> </span></p> +<p id="t26" class="pln"><span class="strut"> </span></p> +<p id="t27" class="stm run hide_run"><span class="nam">three</span><span class="op">(</span><span class="op">)</span><span class="strut"> </span></p> </td> </tr> </table> @@ -129,9 +119,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:40 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_b_branch/index.html b/tests/farm/html/gold_b_branch/index.html index 844f79e1..a0346e86 100644 --- a/tests/farm/html/gold_b_branch/index.html +++ b/tests/farm/html/gold_b_branch/index.html @@ -84,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:40 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_bom/2/bom_py.html b/tests/farm/html/gold_bom/2/bom_py.html index 78c498fd..14f25413 100644 --- a/tests/farm/html/gold_bom/2/bom_py.html +++ b/tests/farm/html/gold_bom/2/bom_py.html @@ -55,35 +55,29 @@ <tr> <td class="linenos"> <p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> -<p id="n6" class="pln"><a href="#n6">6</a></p> -<p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> -<p id="n8" class="pln"><a href="#n8">8</a></p> -<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="stm mis"><a href="#n10">10</a></p> -<p id="n11" class="stm mis"><a href="#n11">11</a></p> -<p id="n12" class="pln"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> -<p id="n14" class="stm run hide_run"><a href="#n14">14</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n5" class="pln"><a href="#n5">5</a></p> +<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> +<p id="n7" class="stm mis"><a href="#n7">7</a></p> +<p id="n8" class="stm mis"><a href="#n8">8</a></p> +<p id="n9" class="pln"><a href="#n9">9</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> +<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> +<p id="t1" class="pln"><span class="com"># A Python source file in utf-8, with BOM.</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> <p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A Python source file in utf-8, with BOM.</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> -<p id="t6" class="pln"><span class="strut"> </span></p> -<p id="t7" class="stm run hide_run"><span class="key">import</span> <span class="nam">sys</span><span class="strut"> </span></p> -<p id="t8" class="pln"><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="key">if</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">version_info</span> <span class="op">>=</span> <span class="op">(</span><span class="num">3</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t10" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> -<p id="t11" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">encode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> -<p id="t12" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> -<p id="t14" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">decode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">sys</span><span class="strut"> </span></p> +<p id="t5" class="pln"><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="key">if</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">version_info</span> <span class="op">>=</span> <span class="op">(</span><span class="num">3</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t7" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> +<p id="t8" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">encode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> +<p id="t9" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> +<p id="t11" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">decode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> </td> </tr> </table> @@ -92,9 +86,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:46 + created at 2018-08-23 06:35 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_bom/2/index.html b/tests/farm/html/gold_bom/2/index.html index 2d285ab1..bde4bb46 100644 --- a/tests/farm/html/gold_bom/2/index.html +++ b/tests/farm/html/gold_bom/2/index.html @@ -76,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:46 + created at 2018-08-23 06:35 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_bom/bom_py.html b/tests/farm/html/gold_bom/bom_py.html index 472f655b..78d7f7b7 100644 --- a/tests/farm/html/gold_bom/bom_py.html +++ b/tests/farm/html/gold_bom/bom_py.html @@ -55,35 +55,29 @@ <tr> <td class="linenos"> <p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> -<p id="n6" class="pln"><a href="#n6">6</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n5" class="pln"><a href="#n5">5</a></p> +<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> -<p id="n8" class="pln"><a href="#n8">8</a></p> -<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="pln"><a href="#n12">12</a></p> -<p id="n13" class="stm mis"><a href="#n13">13</a></p> -<p id="n14" class="stm mis"><a href="#n14">14</a></p> +<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> +<p id="n9" class="pln"><a href="#n9">9</a></p> +<p id="n10" class="stm mis"><a href="#n10">10</a></p> +<p id="n11" class="stm mis"><a href="#n11">11</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> +<p id="t1" class="pln"><span class="com"># A Python source file in utf-8, with BOM.</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> <p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A Python source file in utf-8, with BOM.</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> -<p id="t6" class="pln"><span class="strut"> </span></p> -<p id="t7" class="stm run hide_run"><span class="key">import</span> <span class="nam">sys</span><span class="strut"> </span></p> -<p id="t8" class="pln"><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="key">if</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">version_info</span> <span class="op">>=</span> <span class="op">(</span><span class="num">3</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t10" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">encode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> -<p id="t12" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t13" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> -<p id="t14" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">decode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">sys</span><span class="strut"> </span></p> +<p id="t5" class="pln"><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="key">if</span> <span class="nam">sys</span><span class="op">.</span><span class="nam">version_info</span> <span class="op">>=</span> <span class="op">(</span><span class="num">3</span><span class="op">,</span> <span class="num">0</span><span class="op">)</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t7" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">encode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> +<p id="t9" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t10" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">21</span><span class="strut"> </span></p> +<p id="t11" class="stm mis"> <span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">.</span><span class="nam">decode</span><span class="op">(</span><span class="str">'utf-8'</span><span class="op">)</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> </td> </tr> </table> @@ -92,9 +86,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:44 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_bom/index.html b/tests/farm/html/gold_bom/index.html index 0341c0d0..4c4d9897 100644 --- a/tests/farm/html/gold_bom/index.html +++ b/tests/farm/html/gold_bom/index.html @@ -76,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:44 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_isolatin1/index.html b/tests/farm/html/gold_isolatin1/index.html index ec125364..c648ae7d 100644 --- a/tests/farm/html/gold_isolatin1/index.html +++ b/tests/farm/html/gold_isolatin1/index.html @@ -76,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:40 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_isolatin1/isolatin1_py.html b/tests/farm/html/gold_isolatin1/isolatin1_py.html index 45d13f42..e8ad244b 100644 --- a/tests/farm/html/gold_isolatin1/isolatin1_py.html +++ b/tests/farm/html/gold_isolatin1/isolatin1_py.html @@ -57,21 +57,15 @@ <p id="n1" class="pln"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="pln"><a href="#n6">6</a></p> -<p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> -<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> </td> <td class="text"> <p id="t1" class="pln"><span class="com"># -*- coding: iso8859-1 -*-</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="com"># A Python source file in another encoding.</span><span class="strut"> </span></p> -<p id="t6" class="pln"><span class="strut"> </span></p> -<p id="t7" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> +<p id="t2" class="pln"><span class="com"># A Python source file in another encoding.</span><span class="strut"> </span></p> +<p id="t3" class="pln"><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="nam">math</span> <span class="op">=</span> <span class="str">"3×4 = 12, ÷2 = 6±0"</span><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="key">assert</span> <span class="nam">len</span><span class="op">(</span><span class="nam">math</span><span class="op">)</span> <span class="op">==</span> <span class="num">18</span><span class="strut"> </span></p> </td> </tr> </table> @@ -80,9 +74,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:40 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_1/index.html b/tests/farm/html/gold_omit_1/index.html index 9ea591a4..289c6f10 100644 --- a/tests/farm/html/gold_omit_1/index.html +++ b/tests/farm/html/gold_omit_1/index.html @@ -97,9 +97,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_1/m1_py.html b/tests/farm/html/gold_omit_1/m1_py.html index 1557156c..05b2bd49 100644 --- a/tests/farm/html/gold_omit_1/m1_py.html +++ b/tests/farm/html/gold_omit_1/m1_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_1/m2_py.html b/tests/farm/html/gold_omit_1/m2_py.html index 8f3102d1..056e7af1 100644 --- a/tests/farm/html/gold_omit_1/m2_py.html +++ b/tests/farm/html/gold_omit_1/m2_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m2a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m2b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m2a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m2b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_1/m3_py.html b/tests/farm/html/gold_omit_1/m3_py.html index 2d1e1d4c..428527b2 100644 --- a/tests/farm/html/gold_omit_1/m3_py.html +++ b/tests/farm/html/gold_omit_1/m3_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_1/main_py.html b/tests/farm/html/gold_omit_1/main_py.html index bc93b1a0..3fbc4af7 100644 --- a/tests/farm/html/gold_omit_1/main_py.html +++ b/tests/farm/html/gold_omit_1/main_py.html @@ -54,34 +54,28 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="pln"><a href="#n4">4</a></p> <p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> <p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> <p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t9" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> </td> </tr> </table> @@ -90,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_2/index.html b/tests/farm/html/gold_omit_2/index.html index 8c2576f2..5813c0dc 100644 --- a/tests/farm/html/gold_omit_2/index.html +++ b/tests/farm/html/gold_omit_2/index.html @@ -90,9 +90,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_2/m2_py.html b/tests/farm/html/gold_omit_2/m2_py.html index 8f3102d1..056e7af1 100644 --- a/tests/farm/html/gold_omit_2/m2_py.html +++ b/tests/farm/html/gold_omit_2/m2_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m2a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m2b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m2a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m2b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_2/m3_py.html b/tests/farm/html/gold_omit_2/m3_py.html index 2d1e1d4c..428527b2 100644 --- a/tests/farm/html/gold_omit_2/m3_py.html +++ b/tests/farm/html/gold_omit_2/m3_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_2/main_py.html b/tests/farm/html/gold_omit_2/main_py.html index bc93b1a0..3fbc4af7 100644 --- a/tests/farm/html/gold_omit_2/main_py.html +++ b/tests/farm/html/gold_omit_2/main_py.html @@ -54,34 +54,28 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="pln"><a href="#n4">4</a></p> <p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> <p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> <p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t9" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> </td> </tr> </table> @@ -90,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_3/index.html b/tests/farm/html/gold_omit_3/index.html index f0b32cc4..4ebcf4a4 100644 --- a/tests/farm/html/gold_omit_3/index.html +++ b/tests/farm/html/gold_omit_3/index.html @@ -83,9 +83,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_3/m3_py.html b/tests/farm/html/gold_omit_3/m3_py.html index 2d1e1d4c..428527b2 100644 --- a/tests/farm/html/gold_omit_3/m3_py.html +++ b/tests/farm/html/gold_omit_3/m3_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_3/main_py.html b/tests/farm/html/gold_omit_3/main_py.html index bc93b1a0..3fbc4af7 100644 --- a/tests/farm/html/gold_omit_3/main_py.html +++ b/tests/farm/html/gold_omit_3/main_py.html @@ -54,34 +54,28 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="pln"><a href="#n4">4</a></p> <p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> <p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> <p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t9" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> </td> </tr> </table> @@ -90,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_4/index.html b/tests/farm/html/gold_omit_4/index.html index 7dadd229..e7588714 100644 --- a/tests/farm/html/gold_omit_4/index.html +++ b/tests/farm/html/gold_omit_4/index.html @@ -90,9 +90,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_4/m1_py.html b/tests/farm/html/gold_omit_4/m1_py.html index 1557156c..05b2bd49 100644 --- a/tests/farm/html/gold_omit_4/m1_py.html +++ b/tests/farm/html/gold_omit_4/m1_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_4/m3_py.html b/tests/farm/html/gold_omit_4/m3_py.html index 2d1e1d4c..428527b2 100644 --- a/tests/farm/html/gold_omit_4/m3_py.html +++ b/tests/farm/html/gold_omit_4/m3_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m3a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m3b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_4/main_py.html b/tests/farm/html/gold_omit_4/main_py.html index bc93b1a0..3fbc4af7 100644 --- a/tests/farm/html/gold_omit_4/main_py.html +++ b/tests/farm/html/gold_omit_4/main_py.html @@ -54,34 +54,28 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="pln"><a href="#n4">4</a></p> <p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> <p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> <p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t9" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> </td> </tr> </table> @@ -90,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_5/index.html b/tests/farm/html/gold_omit_5/index.html index b9912d24..e2c1a132 100644 --- a/tests/farm/html/gold_omit_5/index.html +++ b/tests/farm/html/gold_omit_5/index.html @@ -83,9 +83,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_5/m1_py.html b/tests/farm/html/gold_omit_5/m1_py.html index 1557156c..05b2bd49 100644 --- a/tests/farm/html/gold_omit_5/m1_py.html +++ b/tests/farm/html/gold_omit_5/m1_py.html @@ -54,18 +54,12 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> -<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="nam">m1a</span> <span class="op">=</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">m1b</span> <span class="op">=</span> <span class="num">2</span><span class="strut"> </span></p> </td> </tr> </table> @@ -74,9 +68,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_omit_5/main_py.html b/tests/farm/html/gold_omit_5/main_py.html index bc93b1a0..3fbc4af7 100644 --- a/tests/farm/html/gold_omit_5/main_py.html +++ b/tests/farm/html/gold_omit_5/main_py.html @@ -54,34 +54,28 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="pln"><a href="#n4">4</a></p> <p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> <p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> <p id="n7" class="pln"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> <p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> -<p id="n13" class="stm run hide_run"><a href="#n13">13</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> -<p id="t5" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">m1</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="key">import</span> <span class="nam">m2</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">import</span> <span class="nam">m3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> +<p id="t6" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">5</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"><span class="nam">b</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> -<p id="t13" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m1</span><span class="op">.</span><span class="nam">m1a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t9" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m2</span><span class="op">.</span><span class="nam">m2a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">assert</span> <span class="nam">m3</span><span class="op">.</span><span class="nam">m3a</span> <span class="op">==</span> <span class="num">1</span><span class="strut"> </span></p> </td> </tr> </table> @@ -90,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_other/blah_blah_other_py.html b/tests/farm/html/gold_other/blah_blah_other_py.html index 4beb2a07..36e3653d 100644 --- a/tests/farm/html/gold_other/blah_blah_other_py.html +++ b/tests/farm/html/gold_other/blah_blah_other_py.html @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=emulateIE7" /> - <title>Coverage for /Users/ned/coverage/trunk/tests/farm/html/othersrc/other.py: 100%</title> + <title>Coverage for /private/var/folders/j2/gr3cj3jn63s5q8g3bjvw57hm0000gp/T/coverage_test/tests_test_html_HtmlGoldTests_test_other_95946649/othersrc/other.py: 100%</title> <link rel="stylesheet" href="style.css" type="text/css"> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="jquery.hotkeys.js"></script> @@ -16,7 +16,7 @@ <body class="pyfile"> <div id="header"> <div class="content"> - <h1>Coverage for <b>/Users/ned/coverage/trunk/tests/farm/html/othersrc/other.py</b> : + <h1>Coverage for <b>/private/var/folders/j2/gr3cj3jn63s5q8g3bjvw57hm0000gp/T/coverage_test/tests_test_html_HtmlGoldTests_test_other_95946649/othersrc/other.py</b> : <span class="pc_cov">100%</span> </h1> <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" /> @@ -57,19 +57,13 @@ <p id="n1" class="pln"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="pln"><a href="#n6">6</a></p> -<p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> +<p id="t1" class="pln"><span class="com"># A file in another directory. We're checking that it ends up in the</span><span class="strut"> </span></p> +<p id="t2" class="pln"><span class="com"># HTML report.</span><span class="strut"> </span></p> <p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A file in another directory. We're checking that it ends up in the</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="com"># HTML report.</span><span class="strut"> </span></p> -<p id="t6" class="pln"><span class="strut"> </span></p> -<p id="t7" class="stm run hide_run"><span class="nam">print</span><span class="op">(</span><span class="str">"This is the other src!"</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="nam">print</span><span class="op">(</span><span class="str">"This is the other src!"</span><span class="op">)</span><span class="strut"> </span></p> </td> </tr> </table> @@ -78,9 +72,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_other/here_py.html b/tests/farm/html/gold_other/here_py.html index c692a1c4..8efa027a 100644 --- a/tests/farm/html/gold_other/here_py.html +++ b/tests/farm/html/gold_other/here_py.html @@ -54,30 +54,20 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> <p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> -<p id="n7" class="pln"><a href="#n7">7</a></p> -<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> -<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> -<p id="n11" class="stm mis"><a href="#n11">11</a></p> +<p id="n6" class="stm mis"><a href="#n6">6</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A test file for HTML reporting by coverage.py.</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">import</span> <span class="nam">other</span><span class="strut"> </span></p> -<p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"> <span class="nam">h</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t11" class="stm mis"> <span class="nam">h</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">import</span> <span class="nam">other</span><span class="strut"> </span></p> +<p id="t2" class="pln"><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"> <span class="nam">h</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> +<p id="t5" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t6" class="stm mis"> <span class="nam">h</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> </td> </tr> </table> @@ -86,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_other/index.html b/tests/farm/html/gold_other/index.html index 27c194cf..10d4ae9a 100644 --- a/tests/farm/html/gold_other/index.html +++ b/tests/farm/html/gold_other/index.html @@ -60,7 +60,7 @@ </tfoot> <tbody> <tr class="file"> - <td class="name left"><a href="_Users_ned_coverage_trunk_tests_farm_html_othersrc_other_py.html">/Users/ned/coverage/trunk/tests/farm/html/othersrc/other.py</a></td> + <td class="name left"><a href="_private_var_folders_j2_gr3cj3jn63s5q8g3bjvw57hm0000gp_T_coverage_test_tests_test_html_HtmlGoldTests_test_other_95946649_othersrc_other_py.html">/private/var/folders/j2/gr3cj3jn63s5q8g3bjvw57hm0000gp/T/coverage_test/tests_test_html_HtmlGoldTests_test_other_95946649/othersrc/other.py</a></td> <td>1</td> <td>0</td> <td>0</td> @@ -83,9 +83,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_partial/index.html b/tests/farm/html/gold_partial/index.html index ca8919d7..1948615c 100644 --- a/tests/farm/html/gold_partial/index.html +++ b/tests/farm/html/gold_partial/index.html @@ -84,9 +84,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_partial/partial_py.html b/tests/farm/html/gold_partial/partial_py.html index 7f4ed31a..44238f68 100644 --- a/tests/farm/html/gold_partial/partial_py.html +++ b/tests/farm/html/gold_partial/partial_py.html @@ -56,55 +56,47 @@ <tr> <td class="linenos"> <p id="n1" class="pln"><a href="#n1">1</a></p> -<p id="n2" class="pln"><a href="#n2">2</a></p> +<p id="n2" class="stm run hide_run"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> -<p id="n7" class="pln"><a href="#n7">7</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> +<p id="n6" class="pln"><a href="#n6">6</a></p> +<p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> <p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> -<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p> -<p id="n10" class="pln"><a href="#n10">10</a></p> +<p id="n9" class="pln"><a href="#n9">9</a></p> +<p id="n10" class="stm run hide_run"><a href="#n10">10</a></p> <p id="n11" class="stm run hide_run"><a href="#n11">11</a></p> -<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p> +<p id="n12" class="pln"><a href="#n12">12</a></p> <p id="n13" class="pln"><a href="#n13">13</a></p> -<p id="n14" class="stm run hide_run"><a href="#n14">14</a></p> -<p id="n15" class="stm run hide_run"><a href="#n15">15</a></p> +<p id="n14" class="pln"><a href="#n14">14</a></p> +<p id="n15" class="pln"><a href="#n15">15</a></p> <p id="n16" class="pln"><a href="#n16">16</a></p> -<p id="n17" class="pln"><a href="#n17">17</a></p> +<p id="n17" class="stm run hide_run"><a href="#n17">17</a></p> <p id="n18" class="pln"><a href="#n18">18</a></p> -<p id="n19" class="pln"><a href="#n19">19</a></p> -<p id="n20" class="pln"><a href="#n20">20</a></p> -<p id="n21" class="stm run hide_run"><a href="#n21">21</a></p> -<p id="n22" class="pln"><a href="#n22">22</a></p> -<p id="n23" class="stm run hide_run"><a href="#n23">23</a></p> -<p id="n24" class="exc"><a href="#n24">24</a></p> +<p id="n19" class="stm run hide_run"><a href="#n19">19</a></p> +<p id="n20" class="exc"><a href="#n20">20</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> +<p id="t1" class="pln"><span class="com"># partial branches and excluded lines</span><span class="strut"> </span></p> +<p id="t2" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> <p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># partial branches and excluded lines</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="nam">a</span> <span class="op">=</span> <span class="num">6</span><span class="strut"> </span></p> -<p id="t7" class="pln"><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="key">while</span> <span class="key">True</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t9" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> -<p id="t10" class="pln"><span class="strut"> </span></p> -<p id="t11" class="stm run hide_run"><span class="key">while</span> <span class="num">1</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t12" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> -<p id="t13" class="pln"><span class="strut"> </span></p> -<p id="t14" class="stm run hide_run"><span class="key">while</span> <span class="nam">a</span><span class="op">:</span> <span class="com"># pragma: no branch</span><span class="strut"> </span></p> -<p id="t15" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> -<p id="t16" class="pln"><span class="strut"> </span></p> -<p id="t17" class="pln"><span class="key">if</span> <span class="num">0</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t18" class="pln"> <span class="nam">never_happen</span><span class="op">(</span><span class="op">)</span><span class="strut"> </span></p> -<p id="t19" class="pln"><span class="strut"> </span></p> -<p id="t20" class="pln"><span class="key">if</span> <span class="num">1</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t21" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">21</span><span class="strut"> </span></p> -<p id="t22" class="pln"><span class="strut"> </span></p> -<p id="t23" class="stm run hide_run"><span class="key">if</span> <span class="nam">a</span> <span class="op">==</span> <span class="num">23</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t24" class="exc"> <span class="key">raise</span> <span class="nam">AssertionError</span><span class="op">(</span><span class="str">"Can't"</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="key">while</span> <span class="key">True</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> +<p id="t6" class="pln"><span class="strut"> </span></p> +<p id="t7" class="stm run hide_run"><span class="key">while</span> <span class="num">1</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t8" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> +<p id="t9" class="pln"><span class="strut"> </span></p> +<p id="t10" class="stm run hide_run"><span class="key">while</span> <span class="nam">a</span><span class="op">:</span> <span class="com"># pragma: no branch</span><span class="strut"> </span></p> +<p id="t11" class="stm run hide_run"> <span class="key">break</span><span class="strut"> </span></p> +<p id="t12" class="pln"><span class="strut"> </span></p> +<p id="t13" class="pln"><span class="key">if</span> <span class="num">0</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t14" class="pln"> <span class="nam">never_happen</span><span class="op">(</span><span class="op">)</span><span class="strut"> </span></p> +<p id="t15" class="pln"><span class="strut"> </span></p> +<p id="t16" class="pln"><span class="key">if</span> <span class="num">1</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t17" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">21</span><span class="strut"> </span></p> +<p id="t18" class="pln"><span class="strut"> </span></p> +<p id="t19" class="stm run hide_run"><span class="key">if</span> <span class="nam">a</span> <span class="op">==</span> <span class="num">23</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t20" class="exc"> <span class="key">raise</span> <span class="nam">AssertionError</span><span class="op">(</span><span class="str">"Can't"</span><span class="op">)</span><span class="strut"> </span></p> </td> </tr> </table> @@ -113,9 +105,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:43 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_styled/a_py.html b/tests/farm/html/gold_styled/a_py.html index 6e6f317c..dd569b1b 100644 --- a/tests/farm/html/gold_styled/a_py.html +++ b/tests/farm/html/gold_styled/a_py.html @@ -55,28 +55,18 @@ <table> <tr> <td class="linenos"> -<p id="n1" class="pln"><a href="#n1">1</a></p> +<p id="n1" class="stm run hide_run"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> -<p id="n3" class="pln"><a href="#n3">3</a></p> +<p id="n3" class="stm run hide_run"><a href="#n3">3</a></p> <p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="stm run hide_run"><a href="#n6">6</a></p> -<p id="n7" class="pln"><a href="#n7">7</a></p> -<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> -<p id="n9" class="pln"><a href="#n9">9</a></p> -<p id="n10" class="stm mis"><a href="#n10">10</a></p> +<p id="n5" class="stm mis"><a href="#n5">5</a></p> </td> <td class="text"> -<p id="t1" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="com"># A test file for HTML reporting by coverage.py.</span><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="strut"> </span></p> -<p id="t6" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t7" class="pln"> <span class="com"># Needed a < to look at HTML entities.</span><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> -<p id="t9" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> -<p id="t10" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> +<p id="t1" class="stm run hide_run"><span class="key">if</span> <span class="num">1</span> <span class="op"><</span> <span class="num">2</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t2" class="pln"> <span class="com"># Needed a < to look at HTML entities.</span><span class="strut"> </span></p> +<p id="t3" class="stm run hide_run"> <span class="nam">a</span> <span class="op">=</span> <span class="num">3</span><span class="strut"> </span></p> +<p id="t4" class="pln"><span class="key">else</span><span class="op">:</span><span class="strut"> </span></p> +<p id="t5" class="stm mis"> <span class="nam">a</span> <span class="op">=</span> <span class="num">4</span><span class="strut"> </span></p> </td> </tr> </table> @@ -85,9 +75,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:42 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_styled/index.html b/tests/farm/html/gold_styled/index.html index c0881592..1f86b772 100644 --- a/tests/farm/html/gold_styled/index.html +++ b/tests/farm/html/gold_styled/index.html @@ -77,9 +77,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:42 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_unicode/index.html b/tests/farm/html/gold_unicode/index.html index c1f2fb67..35a98a9e 100644 --- a/tests/farm/html/gold_unicode/index.html +++ b/tests/farm/html/gold_unicode/index.html @@ -76,9 +76,9 @@ <div class="content"> <p> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:42 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_unicode/unicode_py.html b/tests/farm/html/gold_unicode/unicode_py.html index 7708f22e..174a9a27 100644 --- a/tests/farm/html/gold_unicode/unicode_py.html +++ b/tests/farm/html/gold_unicode/unicode_py.html @@ -57,21 +57,15 @@ <p id="n1" class="pln"><a href="#n1">1</a></p> <p id="n2" class="pln"><a href="#n2">2</a></p> <p id="n3" class="pln"><a href="#n3">3</a></p> -<p id="n4" class="pln"><a href="#n4">4</a></p> -<p id="n5" class="pln"><a href="#n5">5</a></p> -<p id="n6" class="pln"><a href="#n6">6</a></p> -<p id="n7" class="stm run hide_run"><a href="#n7">7</a></p> -<p id="n8" class="stm run hide_run"><a href="#n8">8</a></p> +<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p> +<p id="n5" class="stm run hide_run"><a href="#n5">5</a></p> </td> <td class="text"> <p id="t1" class="pln"><span class="com"># -*- coding: utf-8 -*-</span><span class="strut"> </span></p> -<p id="t2" class="pln"><span class="com"># Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0</span><span class="strut"> </span></p> -<p id="t3" class="pln"><span class="com"># For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt</span><span class="strut"> </span></p> -<p id="t4" class="pln"><span class="strut"> </span></p> -<p id="t5" class="pln"><span class="com"># A Python source file with exotic characters.</span><span class="strut"> </span></p> -<p id="t6" class="pln"><span class="strut"> </span></p> -<p id="t7" class="stm run hide_run"><span class="nam">upside_down</span> <span class="op">=</span> <span class="str">"ʎd˙ǝbɐɹǝʌoɔ"</span><span class="strut"> </span></p> -<p id="t8" class="stm run hide_run"><span class="nam">surrogate</span> <span class="op">=</span> <span class="str">"db40,dd00: x󠄀"</span><span class="strut"> </span></p> +<p id="t2" class="pln"><span class="com"># A Python source file with exotic characters.</span><span class="strut"> </span></p> +<p id="t3" class="pln"><span class="strut"> </span></p> +<p id="t4" class="stm run hide_run"><span class="nam">upside_down</span> <span class="op">=</span> <span class="str">"ʎd˙ǝbɐɹǝʌoɔ"</span><span class="strut"> </span></p> +<p id="t5" class="stm run hide_run"><span class="nam">surrogate</span> <span class="op">=</span> <span class="str">"db40,dd00: x󠄀"</span><span class="strut"> </span></p> </td> </tr> </table> @@ -80,9 +74,9 @@ <div class="content"> <p> <a class="nav" href="index.html">« index</a> <a class="nav" href="https://coverage.readthedocs.io/en/coverage-5.0a2">coverage.py v5.0a2</a>, - created at 2018-06-29 15:42 + created at 2018-08-22 20:12 </p> </div> </div> </body> -</html>
\ No newline at end of file +</html> diff --git a/tests/farm/html/gold_x_xml/coverage.xml b/tests/farm/html/gold_x_xml/coverage.xml index 162824a0..1030f9f8 100644 --- a/tests/farm/html/gold_x_xml/coverage.xml +++ b/tests/farm/html/gold_x_xml/coverage.xml @@ -1,9 +1,9 @@ <?xml version="1.0" ?> -<coverage branch-rate="0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.6667" lines-covered="2" lines-valid="3" timestamp="1437745880639" version="4.0a7"> - <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/coverage-4.0a7 --> +<coverage branch-rate="0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.6667" lines-covered="2" lines-valid="3" timestamp="1534849155281" version="5.0a2"> + <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/coverage-5.0a2 --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> - <source>/Users/ned/coverage/trunk/tests/farm/html/src</source> + <source>/private/var/folders/j2/gr3cj3jn63s5q8g3bjvw57hm0000gp/T/coverage_test/tests_test_xml_XmlGoldTest_test_a_xml_1_43316963</source> </sources> <packages> <package branch-rate="0" complexity="0" line-rate="0.6667" name="."> @@ -11,9 +11,9 @@ <class branch-rate="0" complexity="0" filename="a.py" line-rate="0.6667" name="a.py"> <methods/> <lines> - <line hits="1" number="6"/> - <line hits="1" number="8"/> - <line hits="0" number="10"/> + <line hits="1" number="1"/> + <line hits="1" number="3"/> + <line hits="0" number="5"/> </lines> </class> </classes> diff --git a/tests/farm/html/gold_y_xml_branch/coverage.xml b/tests/farm/html/gold_y_xml_branch/coverage.xml index bcf1137b..71e08bb0 100644 --- a/tests/farm/html/gold_y_xml_branch/coverage.xml +++ b/tests/farm/html/gold_y_xml_branch/coverage.xml @@ -1,9 +1,9 @@ <?xml version="1.0" ?> -<coverage branch-rate="0.5" branches-covered="1" branches-valid="2" complexity="0" line-rate="0.8" lines-covered="4" lines-valid="5" timestamp="1437745880882" version="4.0a7"> - <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/coverage-4.0a7 --> +<coverage branch-rate="0.5" branches-covered="1" branches-valid="2" complexity="0" line-rate="0.8" lines-covered="4" lines-valid="5" timestamp="1534849423448" version="5.0a2"> + <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/coverage-5.0a2 --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> - <source>/Users/ned/coverage/trunk/tests/farm/html/src</source> + <source>/private/var/folders/j2/gr3cj3jn63s5q8g3bjvw57hm0000gp/T/coverage_test/tests_test_xml_XmlGoldTest_test_y_xml_branch_93378757</source> </sources> <packages> <package branch-rate="0.5" complexity="0" line-rate="0.8" name="."> @@ -11,11 +11,11 @@ <class branch-rate="0.5" complexity="0" filename="y.py" line-rate="0.8" name="y.py"> <methods/> <lines> - <line hits="1" number="6"/> - <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="10" number="7"/> - <line hits="1" number="8"/> - <line hits="0" number="10"/> - <line hits="1" number="12"/> + <line hits="1" number="1"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="5" number="2"/> + <line hits="1" number="3"/> + <line hits="0" number="5"/> + <line hits="1" number="7"/> </lines> </class> </classes> diff --git a/tests/farm/html/othersrc/other.py b/tests/farm/html/othersrc/other.py deleted file mode 100644 index 54b4fb7c..00000000 --- a/tests/farm/html/othersrc/other.py +++ /dev/null @@ -1,7 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A file in another directory. We're checking that it ends up in the -# HTML report. - -print("This is the other src!") diff --git a/tests/farm/html/src/a.py b/tests/farm/html/src/a.py deleted file mode 100644 index f31bdedb..00000000 --- a/tests/farm/html/src/a.py +++ /dev/null @@ -1,10 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A test file for HTML reporting by coverage.py. - -if 1 < 2: - # Needed a < to look at HTML entities. - a = 3 -else: - a = 4 diff --git a/tests/farm/html/src/b.py b/tests/farm/html/src/b.py deleted file mode 100644 index 720cb5f1..00000000 --- a/tests/farm/html/src/b.py +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A test file for HTML reporting by coverage.py. - -def one(x): - # This will be a branch that misses the else. - if x < 2: - a = 3 - else: - a = 4 - -one(1) - -def two(x): - # A missed else that branches to "exit" - if x: - a = 5 - -two(1) - -def three(): - try: - # This if has two branches, *neither* one taken. - if name_error_this_variable_doesnt_exist: - a = 1 - else: - a = 2 - except: - pass - -three() diff --git a/tests/farm/html/src/bom.py b/tests/farm/html/src/bom.py deleted file mode 100644 index 098ad84f..00000000 --- a/tests/farm/html/src/bom.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A Python source file in utf-8, with BOM. -math = "3×4 = 12, ÷2 = 6±0" - -import sys - -if sys.version_info >= (3, 0): - assert len(math) == 18 - assert len(math.encode('utf-8')) == 21 -else: - assert len(math) == 21 - assert len(math.decode('utf-8')) == 18 diff --git a/tests/farm/html/src/extra.css b/tests/farm/html/src/extra.css deleted file mode 100644 index 46c41fcd..00000000 --- a/tests/farm/html/src/extra.css +++ /dev/null @@ -1 +0,0 @@ -/* Doesn't matter what goes in here, it gets copied. */ diff --git a/tests/farm/html/src/here.py b/tests/farm/html/src/here.py deleted file mode 100644 index ca85c75d..00000000 --- a/tests/farm/html/src/here.py +++ /dev/null @@ -1,11 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A test file for HTML reporting by coverage.py. - -import other - -if 1 < 2: - h = 3 -else: - h = 4 diff --git a/tests/farm/html/src/isolatin1.py b/tests/farm/html/src/isolatin1.py deleted file mode 100644 index 69b4a529..00000000 --- a/tests/farm/html/src/isolatin1.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: iso8859-1 -*- -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A Python source file in another encoding. - -math = "34 = 12, 2 = 60" -assert len(math) == 18 diff --git a/tests/farm/html/src/m1.py b/tests/farm/html/src/m1.py deleted file mode 100644 index bef6c9ae..00000000 --- a/tests/farm/html/src/m1.py +++ /dev/null @@ -1,5 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -m1a = 1 -m1b = 2 diff --git a/tests/farm/html/src/m2.py b/tests/farm/html/src/m2.py deleted file mode 100644 index ac75070a..00000000 --- a/tests/farm/html/src/m2.py +++ /dev/null @@ -1,5 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -m2a = 1 -m2b = 2 diff --git a/tests/farm/html/src/m3.py b/tests/farm/html/src/m3.py deleted file mode 100644 index a6f871cd..00000000 --- a/tests/farm/html/src/m3.py +++ /dev/null @@ -1,5 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -m3a = 1 -m3b = 2 diff --git a/tests/farm/html/src/main.py b/tests/farm/html/src/main.py deleted file mode 100644 index 3d0eba65..00000000 --- a/tests/farm/html/src/main.py +++ /dev/null @@ -1,13 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -import m1 -import m2 -import m3 - -a = 5 -b = 6 - -assert m1.m1a == 1 -assert m2.m2a == 1 -assert m3.m3a == 1 diff --git a/tests/farm/html/src/omit4.ini b/tests/farm/html/src/omit4.ini deleted file mode 100644 index 844d3fd0..00000000 --- a/tests/farm/html/src/omit4.ini +++ /dev/null @@ -1,5 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -[report] -omit = m2.py diff --git a/tests/farm/html/src/omit5.ini b/tests/farm/html/src/omit5.ini deleted file mode 100644 index 2615c056..00000000 --- a/tests/farm/html/src/omit5.ini +++ /dev/null @@ -1,11 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -[report] -omit = - fooey - gooey, m[23]*, kablooey - helloworld - -[html] -directory = ../out/omit_5 diff --git a/tests/farm/html/src/partial.ini b/tests/farm/html/src/partial.ini deleted file mode 100644 index 86a1b9bd..00000000 --- a/tests/farm/html/src/partial.ini +++ /dev/null @@ -1,9 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -[run] -branch = True - -[report] -exclude_lines = - raise AssertionError diff --git a/tests/farm/html/src/partial.py b/tests/farm/html/src/partial.py deleted file mode 100644 index ea97ec4f..00000000 --- a/tests/farm/html/src/partial.py +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# partial branches and excluded lines - -a = 6 - -while True: - break - -while 1: - break - -while a: # pragma: no branch - break - -if 0: - never_happen() - -if 1: - a = 21 - -if a == 23: - raise AssertionError("Can't") diff --git a/tests/farm/html/src/run_a_xml_2.ini b/tests/farm/html/src/run_a_xml_2.ini deleted file mode 100644 index 85ba5e8b..00000000 --- a/tests/farm/html/src/run_a_xml_2.ini +++ /dev/null @@ -1,6 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# Put all the XML output in xml_2 -[xml] -output = ../out/xml_2/coverage.xml diff --git a/tests/farm/html/src/tabbed.py b/tests/farm/html/src/tabbed.py deleted file mode 100644 index 573ab126..00000000 --- a/tests/farm/html/src/tabbed.py +++ /dev/null @@ -1,10 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# This file should have tabs. -x = 1 -if x: - a = "Tabbed" # Aligned comments - if x: # look nice - b = "No spaces" # when they - c = "Done" # line up. diff --git a/tests/farm/html/src/unicode.py b/tests/farm/html/src/unicode.py deleted file mode 100644 index c592935b..00000000 --- a/tests/farm/html/src/unicode.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A Python source file with exotic characters. - -upside_down = "ʎd˙ǝbɐɹǝʌoɔ" -surrogate = "db40,dd00: x󠄀" diff --git a/tests/farm/html/src/y.py b/tests/farm/html/src/y.py deleted file mode 100644 index 3ed0ba49..00000000 --- a/tests/farm/html/src/y.py +++ /dev/null @@ -1,12 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -# A test file for XML reporting by coverage.py. - -def choice(x): - if x < 2: - return 3 - else: - return 4 - -assert choice(1) == 3 diff --git a/tests/goldtest.py b/tests/goldtest.py index 8f24f239..48842f0c 100644 --- a/tests/goldtest.py +++ b/tests/goldtest.py @@ -4,39 +4,15 @@ """A test base class for tests based on gold file comparison.""" import os -import sys from unittest_mixins import change_dir # pylint: disable=unused-import -from tests.coveragetest import CoverageTest -from tests.test_farm import clean +from tests.coveragetest import TESTS_DIR # Import helpers, eventually test_farm.py will go away. from tests.test_farm import ( # pylint: disable=unused-import compare, contains, doesnt_contain, contains_any, ) - -class CoverageGoldTest(CoverageTest): - """A test based on gold files.""" - - run_in_temp_dir = False - - def setUp(self): - super(CoverageGoldTest, self).setUp() - self.chdir(self.root_dir) - # Modules should be importable from the current directory. - sys.path.insert(0, '') - - def output_dir(self, the_dir): - """Declare where the output directory is. - - The output directory is deleted at the end of the test, unless the - COVERAGE_KEEP_OUTPUT environment variable is set. - - """ - # To make sure tests are isolated, we always clean the directory at the - # beginning of the test. - clean(the_dir) - - if not os.environ.get("COVERAGE_KEEP_OUTPUT"): # pragma: part covered - self.addCleanup(clean, the_dir) +def gold_path(path): + """Get a path to a gold file for comparison.""" + return os.path.join(TESTS_DIR, "farm", path) diff --git a/tests/test_api.py b/tests/test_api.py index a860c7da..05bde67c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -13,6 +13,7 @@ import warnings import coverage from coverage import env from coverage.backward import StringIO, import_local_file +from coverage.data import line_counts from coverage.misc import CoverageException from coverage.report import Reporter @@ -370,8 +371,12 @@ class ApiTest(CoverageTest): self.make_bad_data_file() cov = coverage.Coverage() warning_regex = ( + r"(" # JSON message: r"Couldn't read data from '.*\.coverage\.foo': " r"CoverageException: Doesn't seem to be a coverage\.py data file" + r"|" # SQL message: + r"Couldn't use data file '.*\.coverage\.foo': file is encrypted or is not a database" + r")" ) with self.assert_warnings(cov, [warning_regex]): cov.combine() @@ -507,8 +512,6 @@ class NamespaceModuleTest(UsingModulesMixin, CoverageTest): class OmitIncludeTestsMixin(UsingModulesMixin, CoverageTestMethodsMixin): """Test methods for coverage methods taking include and omit.""" - run_in_temp_dir = False - def filenames_in(self, summary, filenames): """Assert the `filenames` are in the keys of `summary`.""" for filename in filenames.split(): @@ -576,7 +579,7 @@ class SourceOmitIncludeTest(OmitIncludeTestsMixin, CoverageTest): import usepkgs # pragma: nested # pylint: disable=import-error, unused-variable cov.stop() # pragma: nested data = cov.get_data() - summary = data.line_counts() + summary = line_counts(data) for k, v in list(summary.items()): assert k.endswith(".py") summary[k[:-3]] = v @@ -701,8 +704,6 @@ class TestRunnerPluginTest(CoverageTest): """ def pretend_to_be_nose_with_cover(self, erase): """This is what the nose --with-cover plugin does.""" - cov = coverage.Coverage() - self.make_file("no_biggie.py", """\ a = 1 b = 2 @@ -710,6 +711,7 @@ class TestRunnerPluginTest(CoverageTest): c = 4 """) + cov = coverage.Coverage() if erase: cov.combine() cov.erase() @@ -730,6 +732,34 @@ class TestRunnerPluginTest(CoverageTest): def test_nose_plugin_with_erase(self): self.pretend_to_be_nose_with_cover(erase=True) + def test_pytestcov_parallel(self): + self.make_file("prog.py", """\ + a = 1 + b = 2 + if b == 1: + c = 4 + """) + self.make_file(".coveragerc", """\ + [run] + parallel = True + source = . + """) + + cov = coverage.Coverage(source=None, branch=None, config_file='.coveragerc') + cov.erase() + self.start_import_stop(cov, "prog") + cov.combine() + cov.save() + report = StringIO() + cov.report(show_missing=None, ignore_errors=True, file=report, skip_covered=None) + self.assertEqual(report.getvalue(), textwrap.dedent("""\ + Name Stmts Miss Cover + ----------------------------- + prog.py 4 1 75% + """)) + self.assert_file_count(".coverage", 0) + self.assert_file_count(".coverage.*", 1) + class ReporterDeprecatedAttributeTest(CoverageTest): """Test that Reporter.file_reporters has been deprecated.""" diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index f4fbdbbb..b12f92ea 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -16,7 +16,7 @@ import coverage import coverage.cmdline from coverage import env from coverage.config import CoverageConfig -from coverage.data import CoverageData, CoverageDataFiles +from coverage.data import CoverageData from coverage.misc import ExceptionDuringRun from tests.coveragetest import CoverageTest, OK, ERR, command_line @@ -585,8 +585,7 @@ class CmdLineWithFilesTest(BaseCmdLineTest): "file2.py": dict.fromkeys(range(1, 24)), }) data.add_file_tracers({"file1.py": "a_plugin"}) - data_files = CoverageDataFiles() - data_files.write(data) + data.write() self.command_line("debug data") self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\ @@ -597,16 +596,16 @@ class CmdLineWithFilesTest(BaseCmdLineTest): 2 files: file1.py: 17 lines [a_plugin] file2.py: 23 lines - """).replace("FILENAME", data_files.filename)) + """).replace("FILENAME", data.filename)) def test_debug_data_with_no_data(self): - data_files = CoverageDataFiles() + data = CoverageData() self.command_line("debug data") self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\ -- data ------------------------------------------------------ path: FILENAME No data collected - """).replace("FILENAME", data_files.filename)) + """).replace("FILENAME", data.filename)) class CmdLineStdoutTest(BaseCmdLineTest): diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 58529ec5..9e2d73d9 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -14,6 +14,7 @@ from flaky import flaky import coverage from coverage import env from coverage.backward import import_local_file +from coverage.data import line_counts from coverage.files import abs_file from tests.coveragetest import CoverageTest @@ -235,8 +236,8 @@ class ConcurrencyTest(CoverageTest): # Read the coverage file and see that try_it.py has all its lines # executed. - data = coverage.CoverageData() - data.read_file(".coverage") + data = coverage.CoverageData(".coverage") + data.read() # If the test fails, it's helpful to see this info: fname = abs_file("try_it.py") @@ -245,7 +246,7 @@ class ConcurrencyTest(CoverageTest): print_simple_annotation(code, linenos) lines = line_count(code) - self.assertEqual(data.line_counts()['try_it.py'], lines) + self.assertEqual(line_counts(data)['try_it.py'], lines) def test_threads(self): code = (THREAD + SUM_RANGE_Q + PRINT_SUM_RANGE).format(QLIMIT=self.QLIMIT) diff --git a/tests/test_data.py b/tests/test_data.py index 59c4a5bb..1e6ce027 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -11,8 +11,8 @@ import re import mock -from coverage.backward import StringIO -from coverage.data import CoverageData, CoverageDataFiles, debug_main, canonicalize_json_data +from coverage.data import CoverageData, debug_main, canonicalize_json_data, combine_parallel_data +from coverage.data import add_data_to_hash, line_counts, STORAGE from coverage.debug import DebugControlString from coverage.files import PathAliases, canonical_filename from coverage.misc import CoverageException @@ -74,9 +74,9 @@ MEASURED_FILES_3_4 = ['x.py', 'y.py', 'z.py'] class DataTestHelpers(CoverageTest): """Test helpers for data tests.""" - def assert_line_counts(self, covdata, line_counts, fullpath=False): - """Check that the line_counts of `covdata` is `line_counts`.""" - self.assertEqual(covdata.line_counts(fullpath), line_counts) + def assert_line_counts(self, covdata, counts, fullpath=False): + """Check that the line_counts of `covdata` is `counts`.""" + self.assertEqual(line_counts(covdata, fullpath), counts) def assert_measured_files(self, covdata, measured): """Check that `covdata`'s measured files are `measured`.""" @@ -105,7 +105,10 @@ class DataTestHelpers(CoverageTest): class CoverageDataTest(DataTestHelpers, CoverageTest): """Test cases for CoverageData.""" - run_in_temp_dir = False + # SQL data storage always has files on disk, even without .write(). + # We need to separate the tests so they don't clobber each other. + run_in_temp_dir = STORAGE == "sql" + no_files_in_temp_dir = True def test_empty_data_is_false(self): covdata = CoverageData() @@ -187,6 +190,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): self.assertIsNone(covdata.lines('no_such_file.py')) def test_run_info(self): + self.skip_unless_data_storage_is_json() covdata = CoverageData() self.assertEqual(covdata.run_infos(), []) covdata.add_run_info(hello="there") @@ -230,7 +234,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_lines({"p1.foo": dict.fromkeys([1, 2, 3])}) covdata.add_file_tracers({"p1.foo": "p1.plugin"}) - msg = "Conflicting file tracer name for 'p1.foo': 'p1.plugin' vs 'p1.plugin.foo'" + msg = "Conflicting file tracer name for 'p1.foo': u?'p1.plugin' vs u?'p1.plugin.foo'" with self.assertRaisesRegex(CoverageException, msg): covdata.add_file_tracers({"p1.foo": "p1.plugin.foo"}) @@ -265,6 +269,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): self.assertEqual(covdata3.run_infos(), []) def test_update_run_info(self): + self.skip_unless_data_storage_is_json() covdata1 = CoverageData() covdata1.add_arcs(ARCS_3) covdata1.add_run_info(hello="there", count=17) @@ -337,35 +342,42 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata2.add_lines({"p1.html": dict.fromkeys([1, 2, 3])}) covdata2.add_file_tracers({"p1.html": "html.other_plugin"}) - msg = "Conflicting file tracer name for 'p1.html': 'html.plugin' vs 'html.other_plugin'" + msg = "Conflicting file tracer name for 'p1.html': u?'html.plugin' vs u?'html.other_plugin'" with self.assertRaisesRegex(CoverageException, msg): covdata1.update(covdata2) - msg = "Conflicting file tracer name for 'p1.html': 'html.other_plugin' vs 'html.plugin'" + msg = "Conflicting file tracer name for 'p1.html': u?'html.other_plugin' vs u?'html.plugin'" with self.assertRaisesRegex(CoverageException, msg): covdata2.update(covdata1) def test_update_file_tracer_vs_no_file_tracer(self): - covdata1 = CoverageData() + covdata1 = CoverageData(suffix="1") covdata1.add_lines({"p1.html": dict.fromkeys([1, 2, 3])}) covdata1.add_file_tracers({"p1.html": "html.plugin"}) - covdata2 = CoverageData() + covdata2 = CoverageData(suffix="2") covdata2.add_lines({"p1.html": dict.fromkeys([1, 2, 3])}) - msg = "Conflicting file tracer name for 'p1.html': 'html.plugin' vs ''" + msg = "Conflicting file tracer name for 'p1.html': u?'html.plugin' vs u?''" with self.assertRaisesRegex(CoverageException, msg): covdata1.update(covdata2) - msg = "Conflicting file tracer name for 'p1.html': '' vs 'html.plugin'" + msg = "Conflicting file tracer name for 'p1.html': u?'' vs u?'html.plugin'" with self.assertRaisesRegex(CoverageException, msg): covdata2.update(covdata1) + def test_asking_isnt_measuring(self): + # Asking about an unmeasured file shouldn't make it seem measured. + covdata = CoverageData() + self.assert_measured_files(covdata, []) + self.assertEqual(covdata.arcs("missing.py"), None) + self.assert_measured_files(covdata, []) + def test_add_to_hash_with_lines(self): covdata = CoverageData() covdata.add_lines(LINES_1) hasher = mock.Mock() - covdata.add_to_hash("a.py", hasher) + add_data_to_hash(covdata, "a.py", hasher) self.assertEqual(hasher.method_calls, [ mock.call.update([1, 2]), # lines mock.call.update(""), # file_tracer name @@ -376,7 +388,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_arcs(ARCS_3) covdata.add_file_tracers({"y.py": "hologram_plugin"}) hasher = mock.Mock() - covdata.add_to_hash("y.py", hasher) + add_data_to_hash(covdata, "y.py", hasher) self.assertEqual(hasher.method_calls, [ mock.call.update([(-1, 17), (17, 23), (23, -1)]), # arcs mock.call.update("hologram_plugin"), # file_tracer name @@ -387,7 +399,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata = CoverageData() covdata.add_lines(LINES_1) hasher = mock.Mock() - covdata.add_to_hash("missing.py", hasher) + add_data_to_hash(covdata, "missing.py", hasher) self.assertEqual(hasher.method_calls, [ mock.call.update([]), mock.call.update(None), @@ -399,7 +411,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): covdata.add_arcs(ARCS_3) covdata.add_file_tracers({"y.py": "hologram_plugin"}) hasher = mock.Mock() - covdata.add_to_hash("missing.py", hasher) + add_data_to_hash(covdata, "missing.py", hasher) self.assertEqual(hasher.method_calls, [ mock.call.update([]), mock.call.update(None), @@ -420,12 +432,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest): def test_read_and_write_are_opposites(self): covdata1 = CoverageData() covdata1.add_arcs(ARCS_3) - stringio = StringIO() - covdata1.write_fileobj(stringio) + covdata1.write() - stringio.seek(0) covdata2 = CoverageData() - covdata2.read_fileobj(stringio) + covdata2.read() self.assert_arcs3_data(covdata2) @@ -433,59 +443,60 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest): """Tests of CoverageData that need a temporary directory to make files.""" def test_read_write_lines(self): - covdata1 = CoverageData() + covdata1 = CoverageData("lines.dat") covdata1.add_lines(LINES_1) - covdata1.write_file("lines.dat") + covdata1.write() - covdata2 = CoverageData() - covdata2.read_file("lines.dat") + covdata2 = CoverageData("lines.dat") + covdata2.read() self.assert_lines1_data(covdata2) def test_read_write_arcs(self): - covdata1 = CoverageData() + covdata1 = CoverageData("arcs.dat") covdata1.add_arcs(ARCS_3) - covdata1.write_file("arcs.dat") + covdata1.write() - covdata2 = CoverageData() - covdata2.read_file("arcs.dat") + covdata2 = CoverageData("arcs.dat") + covdata2.read() self.assert_arcs3_data(covdata2) def test_read_errors(self): - covdata = CoverageData() + msg = r"Couldn't .* '.*[/\\]{0}': \S+" - msg = r"Couldn't read data from '{0}': \S+" self.make_file("xyzzy.dat", "xyzzy") with self.assertRaisesRegex(CoverageException, msg.format("xyzzy.dat")): - covdata.read_file("xyzzy.dat") + covdata = CoverageData("xyzzy.dat") + covdata.read() + self.assertFalse(covdata) self.make_file("empty.dat", "") with self.assertRaisesRegex(CoverageException, msg.format("empty.dat")): - covdata.read_file("empty.dat") - - with self.assertRaisesRegex(CoverageException, msg.format("nonexistent.dat")): - covdata.read_file("nonexistent.dat") - - self.make_file("misleading.dat", CoverageData._GO_AWAY + " this isn't JSON") - with self.assertRaisesRegex(CoverageException, msg.format("misleading.dat")): - covdata.read_file("misleading.dat") - - # After all that, no data should be in our CoverageData. + covdata = CoverageData("empty.dat") + covdata.read() self.assertFalse(covdata) + if STORAGE == "json": + self.make_file("misleading.dat", CoverageData._GO_AWAY + " this isn't JSON") + with self.assertRaisesRegex(CoverageException, msg.format("misleading.dat")): + covdata = CoverageData("misleading.dat") + covdata.read() + self.assertFalse(covdata) + def test_debug_main(self): - covdata1 = CoverageData() + self.skip_unless_data_storage_is_json() + covdata1 = CoverageData(".coverage") covdata1.add_lines(LINES_1) - covdata1.write_file(".coverage") + covdata1.write() debug_main([]) - covdata2 = CoverageData() + covdata2 = CoverageData("arcs.dat") covdata2.add_arcs(ARCS_3) covdata2.add_file_tracers({"y.py": "magic_plugin"}) covdata2.add_run_info(version="v3.14", chunks=["z", "a"]) - covdata2.write_file("arcs.dat") + covdata2.write() - covdata3 = CoverageData() - covdata3.write_file("empty.dat") + covdata3 = CoverageData("empty.dat") + covdata3.write() debug_main(["arcs.dat", "empty.dat"]) expected = { @@ -518,27 +529,23 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest): class CoverageDataFilesTest(DataTestHelpers, CoverageTest): - """Tests of CoverageDataFiles.""" + """Tests of CoverageData file handling.""" no_files_in_temp_dir = True - def setUp(self): - super(CoverageDataFilesTest, self).setUp() - self.data_files = CoverageDataFiles() - def test_reading_missing(self): self.assert_doesnt_exist(".coverage") covdata = CoverageData() - self.data_files.read(covdata) + covdata.read() self.assert_line_counts(covdata, {}) def test_writing_and_reading(self): covdata1 = CoverageData() covdata1.add_lines(LINES_1) - self.data_files.write(covdata1) + covdata1.write() covdata2 = CoverageData() - self.data_files.read(covdata2) + covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) def test_debug_output_with_debug_option(self): @@ -547,16 +554,22 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): debug = DebugControlString(options=["dataio"]) covdata1 = CoverageData(debug=debug) covdata1.add_lines(LINES_1) - self.data_files.write(covdata1) + covdata1.write() covdata2 = CoverageData(debug=debug) - self.data_files.read(covdata2) + covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) self.assertRegex( debug.get_output(), + r"(" # JSON output: r"^Writing data to '.*\.coverage'\n" r"Reading data from '.*\.coverage'\n$" + r"|" # SQL output: + r"Erasing data file '.*\.coverage'\n" + r"Creating data file '.*\.coverage'\n" + r"Opening data file '.*\.coverage'\n$" + r")" ) def test_debug_output_without_debug_option(self): @@ -565,19 +578,19 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): debug = DebugControlString(options=[]) covdata1 = CoverageData(debug=debug) covdata1.add_lines(LINES_1) - self.data_files.write(covdata1) + covdata1.write() covdata2 = CoverageData(debug=debug) - self.data_files.read(covdata2) + covdata2.read() self.assert_line_counts(covdata2, SUMMARY_1) self.assertEqual(debug.get_output(), "") def test_explicit_suffix(self): self.assert_doesnt_exist(".coverage.SUFFIX") - covdata = CoverageData() + covdata = CoverageData(suffix='SUFFIX') covdata.add_lines(LINES_1) - self.data_files.write(covdata, suffix='SUFFIX') + covdata.write() self.assert_exists(".coverage.SUFFIX") self.assert_doesnt_exist(".coverage") @@ -585,17 +598,17 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): self.assert_file_count(".coverage.*", 0) # suffix=True will make a randomly named data file. - covdata1 = CoverageData() + covdata1 = CoverageData(suffix=True) covdata1.add_lines(LINES_1) - self.data_files.write(covdata1, suffix=True) + covdata1.write() self.assert_doesnt_exist(".coverage") data_files1 = glob.glob(".coverage.*") self.assertEqual(len(data_files1), 1) # Another suffix=True will choose a different name. - covdata2 = CoverageData() + covdata2 = CoverageData(suffix=True) covdata2.add_lines(LINES_1) - self.data_files.write(covdata2, suffix=True) + covdata2.write() self.assert_doesnt_exist(".coverage") data_files2 = glob.glob(".coverage.*") self.assertEqual(len(data_files2), 2) @@ -606,20 +619,20 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): def test_combining(self): self.assert_file_count(".coverage.*", 0) - covdata1 = CoverageData() + covdata1 = CoverageData(suffix='1') covdata1.add_lines(LINES_1) - self.data_files.write(covdata1, suffix='1') + covdata1.write() self.assert_exists(".coverage.1") self.assert_file_count(".coverage.*", 1) - covdata2 = CoverageData() + covdata2 = CoverageData(suffix='2') covdata2.add_lines(LINES_2) - self.data_files.write(covdata2, suffix='2') + covdata2.write() self.assert_exists(".coverage.2") self.assert_file_count(".coverage.*", 2) covdata3 = CoverageData() - self.data_files.combine_parallel_data(covdata3) + combine_parallel_data(covdata3) self.assert_line_counts(covdata3, SUMMARY_1_2) self.assert_measured_files(covdata3, MEASURED_FILES_1_2) self.assert_file_count(".coverage.*", 0) @@ -627,27 +640,27 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): def test_erasing(self): covdata1 = CoverageData() covdata1.add_lines(LINES_1) - self.data_files.write(covdata1) + covdata1.write() covdata1.erase() self.assert_line_counts(covdata1, {}) - self.data_files.erase() covdata2 = CoverageData() - self.data_files.read(covdata2) + covdata2.read() self.assert_line_counts(covdata2, {}) def test_erasing_parallel(self): self.make_file("datafile.1") self.make_file("datafile.2") self.make_file(".coverage") - data_files = CoverageDataFiles("datafile") - data_files.erase(parallel=True) + data = CoverageData("datafile") + data.erase(parallel=True) self.assert_file_count("datafile.*", 0) self.assert_exists(".coverage") def read_json_data_file(self, fname): """Read a JSON data file for testing the JSON directly.""" + self.skip_unless_data_storage_is_json() with open(fname, 'r') as fdata: go_away = fdata.read(len(CoverageData._GO_AWAY)) self.assertEqual(go_away, CoverageData._GO_AWAY) @@ -657,7 +670,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): # Write with CoverageData, then read the JSON explicitly. covdata = CoverageData() covdata.add_lines(LINES_1) - self.data_files.write(covdata) + covdata.write() data = self.read_json_data_file(".coverage") @@ -674,7 +687,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): # Write with CoverageData, then read the JSON explicitly. covdata = CoverageData() covdata.add_arcs(ARCS_3) - self.data_files.write(covdata) + covdata.write() data = self.read_json_data_file(".coverage") @@ -687,19 +700,19 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): self.assertNotIn('file_tracers', data) def test_writing_to_other_file(self): - data_files = CoverageDataFiles(".otherfile") - covdata = CoverageData() + self.skipTest("This will be deleted!") # TODO + covdata = CoverageData(".otherfile") covdata.add_lines(LINES_1) - data_files.write(covdata) + covdata.write() self.assert_doesnt_exist(".coverage") self.assert_exists(".otherfile") - data_files.write(covdata, suffix="extra") + covdata.write(suffix="extra") self.assert_exists(".otherfile.extra") self.assert_doesnt_exist(".coverage") def test_combining_with_aliases(self): - covdata1 = CoverageData() + covdata1 = CoverageData(suffix='1') covdata1.add_lines({ '/home/ned/proj/src/a.py': {1: None, 2: None}, '/home/ned/proj/src/sub/b.py': {3: None}, @@ -708,14 +721,14 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata1.add_file_tracers({ '/home/ned/proj/src/template.html': 'html.plugin', }) - self.data_files.write(covdata1, suffix='1') + covdata1.write() - covdata2 = CoverageData() + covdata2 = CoverageData(suffix='2') covdata2.add_lines({ r'c:\ned\test\a.py': {4: None, 5: None}, r'c:\ned\test\sub\b.py': {3: None, 6: None}, }) - self.data_files.write(covdata2, suffix='2') + covdata2.write() self.assert_file_count(".coverage.*", 2) @@ -723,7 +736,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): aliases = PathAliases() aliases.add("/home/ned/proj/src/", "./") aliases.add(r"c:\ned\test", "./") - self.data_files.combine_parallel_data(covdata3, aliases=aliases) + combine_parallel_data(covdata3, aliases=aliases) self.assert_file_count(".coverage.*", 0) # covdata3 hasn't been written yet. Should this file exist or not? #self.assert_exists(".coverage") @@ -737,23 +750,23 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): self.assertEqual(covdata3.file_tracer(template_html), 'html.plugin') def test_combining_from_different_directories(self): - covdata1 = CoverageData() - covdata1.add_lines(LINES_1) os.makedirs('cov1') - covdata1.write_file('cov1/.coverage.1') + covdata1 = CoverageData('cov1/.coverage.1') + covdata1.add_lines(LINES_1) + covdata1.write() - covdata2 = CoverageData() - covdata2.add_lines(LINES_2) os.makedirs('cov2') - covdata2.write_file('cov2/.coverage.2') + covdata2 = CoverageData('cov2/.coverage.2') + covdata2.add_lines(LINES_2) + covdata2.write() # This data won't be included. - covdata_xxx = CoverageData() + covdata_xxx = CoverageData('.coverage.xxx') covdata_xxx.add_arcs(ARCS_3) - covdata_xxx.write_file('.coverage.xxx') + covdata_xxx.write() covdata3 = CoverageData() - self.data_files.combine_parallel_data(covdata3, data_paths=['cov1', 'cov2']) + combine_parallel_data(covdata3, data_paths=['cov1', 'cov2']) self.assert_line_counts(covdata3, SUMMARY_1_2) self.assert_measured_files(covdata3, MEASURED_FILES_1_2) @@ -762,24 +775,27 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): self.assert_exists(".coverage.xxx") def test_combining_from_files(self): - covdata1 = CoverageData() - covdata1.add_lines(LINES_1) os.makedirs('cov1') - covdata1.write_file('cov1/.coverage.1') + covdata1 = CoverageData('cov1/.coverage.1') + covdata1.add_lines(LINES_1) + covdata1.write() - covdata2 = CoverageData() - covdata2.add_lines(LINES_2) os.makedirs('cov2') - covdata2.write_file('cov2/.coverage.2') + covdata2 = CoverageData('cov2/.coverage.2') + covdata2.add_lines(LINES_2) + covdata2.write() # This data won't be included. - covdata_xxx = CoverageData() + covdata_xxx = CoverageData('.coverage.xxx') covdata_xxx.add_arcs(ARCS_3) - covdata_xxx.write_file('.coverage.xxx') - covdata_xxx.write_file('cov2/.coverage.xxx') + covdata_xxx.write() + + covdata_2xxx = CoverageData('cov2/.coverage.xxx') + covdata_2xxx.add_arcs(ARCS_3) + covdata_2xxx.write() covdata3 = CoverageData() - self.data_files.combine_parallel_data(covdata3, data_paths=['cov1', 'cov2/.coverage.2']) + combine_parallel_data(covdata3, data_paths=['cov1', 'cov2/.coverage.2']) self.assert_line_counts(covdata3, SUMMARY_1_2) self.assert_measured_files(covdata3, MEASURED_FILES_1_2) @@ -792,4 +808,4 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest): covdata = CoverageData() msg = "Couldn't combine from non-existent path 'xyzzy'" with self.assertRaisesRegex(CoverageException, msg): - self.data_files.combine_parallel_data(covdata, data_paths=['xyzzy']) + combine_parallel_data(covdata, data_paths=['xyzzy']) diff --git a/tests/test_debug.py b/tests/test_debug.py index 2699ca61..c47dd343 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -128,18 +128,23 @@ class DebugTraceTest(CoverageTest): def test_debug_callers(self): out_lines = self.f1_debug_output(["pid", "dataop", "dataio", "callers"]) print(out_lines) - # For every real message, there should be a stack - # trace with a line like "f1_debug_output : /Users/ned/coverage/tests/test_debug.py @71" + # For every real message, there should be a stack trace with a line like + # "f1_debug_output : /Users/ned/coverage/tests/test_debug.py @71" real_messages = re_lines(out_lines, r" @\d+", match=False).splitlines() frame_pattern = r"\s+f1_debug_output : .*tests[/\\]test_debug.py @\d+$" frames = re_lines(out_lines, frame_pattern).splitlines() self.assertEqual(len(real_messages), len(frames)) # The last message should be "Writing data", and the last frame should - # be write_file in data.py. - self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Writing data") + # be _write_file in data.py. last_line = out_lines.splitlines()[-1] - self.assertRegex(last_line, r"\s+write_file : .*coverage[/\\]data.py @\d+$") + from coverage.data import STORAGE + if STORAGE == "json": + self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Writing data") + self.assertRegex(last_line, r"\s+_write_file : .*coverage[/\\]data.py @\d+$") + else: + self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Creating data file") + self.assertRegex(last_line, r"\s+_create_db : .*coverage[/\\]sqldata.py @\d+$") def test_debug_config(self): out_lines = self.f1_debug_output(["config"]) diff --git a/tests/test_farm.py b/tests/test_farm.py index 942bdd5c..54eeb499 100644 --- a/tests/test_farm.py +++ b/tests/test_farm.py @@ -20,7 +20,6 @@ from tests.backtest import execfile # pylint: disable=redefined-builtin from coverage import env from coverage.backunittest import unittest -from coverage.debug import _TEST_NAME_FILE # Look for files that become tests. @@ -105,10 +104,6 @@ class FarmTestCase(ModuleAwareMixin, SysPathAwareMixin, unittest.TestCase): def __call__(self): # pylint: disable=arguments-differ """Execute the test from the runpy file.""" - if _TEST_NAME_FILE: # pragma: debugging - with open(_TEST_NAME_FILE, "w") as f: - f.write(self.description.replace("/", "_")) - # Prepare a dictionary of globals for the run.py files to use. fns = """ copy run clean skip diff --git a/tests/test_html.py b/tests/test_html.py index 9706cd33..b4dd4606 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -20,7 +20,7 @@ import coverage.html from coverage.misc import CoverageException, NotPython, NoSource from tests.coveragetest import CoverageTest, TESTS_DIR -from tests.goldtest import CoverageGoldTest +from tests.goldtest import gold_path from tests.goldtest import change_dir, compare, contains, doesnt_contain, contains_any @@ -579,6 +579,11 @@ def compare_html(dir1, dir2): (r'/Users/ned/coverage/trunk/tests', 'TESTS_DIR'), (flat_rootname(unicode_class(TESTS_DIR)), '_TESTS_DIR'), (flat_rootname(u'/Users/ned/coverage/trunk/tests'), '_TESTS_DIR'), + # The temp dir the tests make. + (re.escape(os.getcwd()), 'TEST_TMPDIR'), + (flat_rootname(unicode_class(os.getcwd())), '_TEST_TMPDIR'), + (r'/private/var/folders/[\w/]{35}/coverage_test/tests_test_html_\w+_\d{8}', 'TEST_TMPDIR'), + (r'_private_var_folders_\w{35}_coverage_test_tests_test_html_\w+_\d{8}', '_TEST_TMPDIR'), ] if env.WINDOWS: # For file paths... @@ -586,25 +591,27 @@ def compare_html(dir1, dir2): return compare(dir1, dir2, file_pattern="*.html", scrubs=scrubs) -class HtmlGoldTests(CoverageGoldTest): +class HtmlGoldTests(CoverageTest): """Tests of HTML reporting that use gold files.""" - root_dir = 'tests/farm/html' - def test_a(self): - self.output_dir("out/a") + self.make_file("a.py", """\ + if 1 < 2: + # Needed a < to look at HTML entities. + a = 3 + else: + a = 4 + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import a # pragma: nested - cov.stop() # pragma: nested - cov.html_report(a, directory='../out/a') + cov = coverage.Coverage() + cov.start() + import a # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(a, directory='out') - compare_html("gold_a", "out/a") + compare_html("out", gold_path("html/gold_a")) contains( - "out/a/a_py.html", + "out/a_py.html", ('<span class="key">if</span> <span class="num">1</span> ' '<span class="op"><</span> <span class="num">2</span>'), (' <span class="nam">a</span> ' @@ -612,226 +619,345 @@ class HtmlGoldTests(CoverageGoldTest): '<span class="pc_cov">67%</span>', ) contains( - "out/a/index.html", + "out/index.html", '<a href="a_py.html">a.py</a>', '<span class="pc_cov">67%</span>', '<td class="right" data-ratio="2 3">67%</td>', ) def test_b_branch(self): - self.output_dir("out/b_branch") + self.make_file("b.py", """\ + def one(x): + # This will be a branch that misses the else. + if x < 2: + a = 3 + else: + a = 4 + + one(1) + + def two(x): + # A missed else that branches to "exit" + if x: + a = 5 + + two(1) + + def three(): + try: + # This if has two branches, *neither* one taken. + if name_error_this_variable_doesnt_exist: + a = 1 + else: + a = 2 + except: + pass + + three() + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(branch=True) - cov.start() - import b # pragma: nested - cov.stop() # pragma: nested - cov.html_report(b, directory="../out/b_branch") + cov = coverage.Coverage(branch=True) + cov.start() + import b # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(b, directory="out") - compare_html("gold_b_branch", "out/b_branch") + compare_html("out", gold_path("html/gold_b_branch")) contains( - "out/b_branch/b_py.html", + "out/b_py.html", ('<span class="key">if</span> <span class="nam">x</span> ' '<span class="op"><</span> <span class="num">2</span>'), (' <span class="nam">a</span> <span class="op">=</span> ' '<span class="num">3</span>'), '<span class="pc_cov">70%</span>', - ('<span class="annotate short">8 ↛ 11</span>' - '<span class="annotate long">line 8 didn\'t jump to line 11, ' - 'because the condition on line 8 was never false</span>'), - ('<span class="annotate short">17 ↛ exit</span>' - '<span class="annotate long">line 17 didn\'t return from function \'two\', ' - 'because the condition on line 17 was never false</span>'), - ('<span class="annotate short">25 ↛ 26, ' - '25 ↛ 28</span>' + + ('<span class="annotate short">3 ↛ 6</span>' + '<span class="annotate long">line 3 didn\'t jump to line 6, ' + 'because the condition on line 3 was never false</span>'), + ('<span class="annotate short">12 ↛ exit</span>' + '<span class="annotate long">line 12 didn\'t return from function \'two\', ' + 'because the condition on line 12 was never false</span>'), + ('<span class="annotate short">20 ↛ 21, ' + '20 ↛ 23</span>' '<span class="annotate long">2 missed branches: ' - '1) line 25 didn\'t jump to line 26, ' - 'because the condition on line 25 was never true, ' - '2) line 25 didn\'t jump to line 28, ' - 'because the condition on line 25 was never false</span>'), + '1) line 20 didn\'t jump to line 21, ' + 'because the condition on line 20 was never true, ' + '2) line 20 didn\'t jump to line 23, ' + 'because the condition on line 20 was never false</span>'), ) contains( - "out/b_branch/index.html", + "out/index.html", '<a href="b_py.html">b.py</a>', '<span class="pc_cov">70%</span>', '<td class="right" data-ratio="16 23">70%</td>', ) def test_bom(self): - self.output_dir("out/bom") + self.make_file("bom.py", bytes=b"""\ +\xef\xbb\xbf# A Python source file in utf-8, with BOM. +math = "3\xc3\x974 = 12, \xc3\xb72 = 6\xc2\xb10" - with change_dir("src"): - # It's important that the source file really have a BOM, which can - # get lost, so check that it's really there. - with open("bom.py", "rb") as f: - first_three = f.read(3) - assert first_three == b"\xef\xbb\xbf" - - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import bom # pragma: nested - cov.stop() # pragma: nested - cov.html_report(bom, directory="../out/bom") +import sys - compare_html("gold_bom", "out/bom") +if sys.version_info >= (3, 0): + assert len(math) == 18 + assert len(math.encode('utf-8')) == 21 +else: + assert len(math) == 21 + assert len(math.decode('utf-8')) == 18 +""".replace(b"\n", b"\r\n")) + + # It's important that the source file really have a BOM, which can + # get lost, so check that it's really there, and that we have \r\n + # line endings. + with open("bom.py", "rb") as f: + data = f.read() + assert data[:3] == b"\xef\xbb\xbf" + assert data.count(b"\r\n") == 11 + + cov = coverage.Coverage() + cov.start() + import bom # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(bom, directory="out") + + compare_html("out", gold_path("html/gold_bom")) contains( - "out/bom/bom_py.html", + "out/bom_py.html", '<span class="str">"3×4 = 12, ÷2 = 6±0"</span>', ) def test_isolatin1(self): - self.output_dir("out/isolatin1") + self.make_file("isolatin1.py", bytes=b"""\ +# -*- coding: iso8859-1 -*- +# A Python source file in another encoding. - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import isolatin1 # pragma: nested - cov.stop() # pragma: nested - cov.html_report(isolatin1, directory="../out/isolatin1") +math = "3\xd74 = 12, \xf72 = 6\xb10" +assert len(math) == 18 +""") - compare_html("gold_isolatin1", "out/isolatin1") + cov = coverage.Coverage() + cov.start() + import isolatin1 # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(isolatin1, directory="out") + + compare_html("out", gold_path("html/gold_isolatin1")) contains( - "out/isolatin1/isolatin1_py.html", + "out/isolatin1_py.html", '<span class="str">"3×4 = 12, ÷2 = 6±0"</span>', ) + def make_main_etc(self): + self.make_file("main.py", """\ + import m1 + import m2 + import m3 + + a = 5 + b = 6 + + assert m1.m1a == 1 + assert m2.m2a == 1 + assert m3.m3a == 1 + """) + self.make_file("m1.py", """\ + m1a = 1 + m1b = 2 + """) + self.make_file("m2.py", """\ + m2a = 1 + m2b = 2 + """) + self.make_file("m3.py", """\ + m3a = 1 + m3b = 2 + """) + def test_omit_1(self): - self.output_dir("out/omit_1") + self.make_main_etc() - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(include=["./*"]) - cov.start() - import main # pragma: nested # pylint: disable=unused-variable - cov.stop() # pragma: nested - cov.html_report(directory="../out/omit_1") + cov = coverage.Coverage(include=["./*"]) + cov.start() + import main # pragma: nested # pylint: disable=unused-variable, import-error + cov.stop() # pragma: nested + cov.html_report(directory="out") - compare_html("gold_omit_1", "out/omit_1") + compare_html("out", gold_path("html/gold_omit_1")) def test_omit_2(self): - self.output_dir("out/omit_2") + self.make_main_etc() - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(include=["./*"]) - cov.start() - import main # pragma: nested # pylint: disable=unused-variable - cov.stop() # pragma: nested - cov.html_report(directory="../out/omit_2", omit=["m1.py"]) + cov = coverage.Coverage(include=["./*"]) + cov.start() + import main # pragma: nested # pylint: disable=unused-variable, import-error + cov.stop() # pragma: nested + cov.html_report(directory="out", omit=["m1.py"]) - compare_html("gold_omit_2", "out/omit_2") + compare_html("out", gold_path("html/gold_omit_2")) def test_omit_3(self): - self.output_dir("out/omit_3") + self.make_main_etc() - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(include=["./*"]) - cov.start() - import main # pragma: nested # pylint: disable=unused-variable - cov.stop() # pragma: nested - cov.html_report(directory="../out/omit_3", omit=["m1.py", "m2.py"]) + cov = coverage.Coverage(include=["./*"]) + cov.start() + import main # pragma: nested # pylint: disable=unused-variable, import-error + cov.stop() # pragma: nested + cov.html_report(directory="out", omit=["m1.py", "m2.py"]) - compare_html("gold_omit_3", "out/omit_3") + compare_html("out", gold_path("html/gold_omit_3")) def test_omit_4(self): - self.output_dir("out/omit_4") + self.make_main_etc() + self.make_file("omit4.ini", """\ + [report] + omit = m2.py + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(config_file="omit4.ini", include=["./*"]) - cov.start() - import main # pragma: nested # pylint: disable=unused-variable - cov.stop() # pragma: nested - cov.html_report(directory="../out/omit_4") + cov = coverage.Coverage(config_file="omit4.ini", include=["./*"]) + cov.start() + import main # pragma: nested # pylint: disable=unused-variable, import-error + cov.stop() # pragma: nested + cov.html_report(directory="out") - compare_html("gold_omit_4", "out/omit_4") + compare_html("out", gold_path("html/gold_omit_4")) def test_omit_5(self): - self.output_dir("out/omit_5") + self.make_main_etc() + self.make_file("omit5.ini", """\ + [report] + omit = + fooey + gooey, m[23]*, kablooey + helloworld + + [html] + directory = out/omit_5 + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(config_file="omit5.ini", include=["./*"]) - cov.start() - import main # pragma: nested # pylint: disable=unused-variable - cov.stop() # pragma: nested - cov.html_report() + cov = coverage.Coverage(config_file="omit5.ini", include=["./*"]) + cov.start() + import main # pragma: nested # pylint: disable=unused-variable, import-error + cov.stop() # pragma: nested + cov.html_report() - compare_html("gold_omit_5", "out/omit_5") + compare_html("out/omit_5", gold_path("html/gold_omit_5")) def test_other(self): - self.output_dir("out/other") + self.make_file("src/here.py", """\ + import other + + if 1 < 2: + h = 3 + else: + h = 4 + """) + self.make_file("othersrc/other.py", """\ + # A file in another directory. We're checking that it ends up in the + # HTML report. + + print("This is the other src!") + """) with change_dir("src"): - # pylint: disable=import-error + sys.path.insert(0, "") # pytest sometimes has this, sometimes not!? sys.path.insert(0, "../othersrc") cov = coverage.Coverage(include=["./*", "../othersrc/*"]) cov.start() - import here # pragma: nested # pylint: disable=unused-variable + import here # pragma: nested # pylint: disable=unused-variable, import-error cov.stop() # pragma: nested - cov.html_report(directory="../out/other") + cov.html_report(directory="../out") # Different platforms will name the "other" file differently. Rename it - for p in glob.glob("out/other/*_other_py.html"): - os.rename(p, "out/other/blah_blah_other_py.html") + for p in glob.glob("out/*_other_py.html"): + os.rename(p, "out/blah_blah_other_py.html") - compare_html("gold_other", "out/other") + compare_html("out", gold_path("html/gold_other")) contains( - "out/other/index.html", + "out/index.html", '<a href="here_py.html">here.py</a>', 'other_py.html">', 'other.py</a>', ) def test_partial(self): - self.output_dir("out/partial") + self.make_file("partial.py", """\ + # partial branches and excluded lines + a = 6 - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(config_file="partial.ini") - cov.start() - import partial # pragma: nested - cov.stop() # pragma: nested - cov.html_report(partial, directory="../out/partial") + while True: + break - compare_html("gold_partial", "out/partial") + while 1: + break + + while a: # pragma: no branch + break + + if 0: + never_happen() + + if 1: + a = 21 + + if a == 23: + raise AssertionError("Can't") + """) + self.make_file("partial.ini", """\ + [run] + branch = True + + [report] + exclude_lines = + raise AssertionError + """) + + cov = coverage.Coverage(config_file="partial.ini") + cov.start() + import partial # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(partial, directory="out") + + compare_html("out", gold_path("html/gold_partial")) contains( - "out/partial/partial_py.html", - '<p id="t8" class="stm run hide_run">', - '<p id="t11" class="stm run hide_run">', - '<p id="t14" class="stm run hide_run">', + "out/partial_py.html", + '<p id="t4" class="stm run hide_run">', + '<p id="t7" class="stm run hide_run">', + '<p id="t10" class="stm run hide_run">', # The "if 0" and "if 1" statements are optimized away. - '<p id="t17" class="pln">', + '<p id="t13" class="pln">', # The "raise AssertionError" is excluded by regex in the .ini. - '<p id="t24" class="exc">', + '<p id="t20" class="exc">', ) contains( - "out/partial/index.html", + "out/index.html", '<a href="partial_py.html">partial.py</a>', ) contains( - "out/partial/index.html", + "out/index.html", '<span class="pc_cov">100%</span>' ) def test_styled(self): - self.output_dir("out/styled") + self.make_file("a.py", """\ + if 1 < 2: + # Needed a < to look at HTML entities. + a = 3 + else: + a = 4 + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import a # pragma: nested - cov.stop() # pragma: nested - cov.html_report(a, directory="../out/styled", extra_css="extra.css") + self.make_file("extra.css", "/* Doesn't matter what goes in here, it gets copied. */") + + cov = coverage.Coverage() + cov.start() + import a # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(a, directory="out", extra_css="extra.css") - compare_html("gold_styled", "out/styled") - compare("gold_styled", "out/styled", size_within=10, file_pattern="*.css") + compare_html("out", gold_path("html/gold_styled")) + compare("out", gold_path("html/gold_styled"), size_within=10, file_pattern="*.css") contains( - "out/styled/a_py.html", + "out/a_py.html", '<link rel="stylesheet" href="extra.css" type="text/css">', ('<span class="key">if</span> <span class="num">1</span> ' '<span class="op"><</span> <span class="num">2</span>'), @@ -840,55 +966,72 @@ class HtmlGoldTests(CoverageGoldTest): '<span class="pc_cov">67%</span>' ) contains( - "out/styled/index.html", + "out/index.html", '<link rel="stylesheet" href="extra.css" type="text/css">', '<a href="a_py.html">a.py</a>', '<span class="pc_cov">67%</span>' ) def test_tabbed(self): - self.output_dir("out/tabbed") + # The file contents would look like this with 8-space tabs: + # x = 1 + # if x: + # a = "tabbed" # aligned comments + # if x: # look nice + # b = "no spaces" # when they + # c = "done" # line up. + self.make_file("tabbed.py", """\ + x = 1 + if x: + \ta = "Tabbed"\t\t\t\t# Aligned comments + \tif x:\t\t\t\t\t# look nice + \t\tb = "No spaces"\t\t\t# when they + \tc = "Done"\t\t\t\t# line up. + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import tabbed # pragma: nested - cov.stop() # pragma: nested - cov.html_report(tabbed, directory="../out/tabbed") + cov = coverage.Coverage() + cov.start() + import tabbed # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.html_report(tabbed, directory="out") # Editors like to change things, make sure our source file still has tabs. - contains("src/tabbed.py", "\tif x:\t\t\t\t\t# look nice") + contains("tabbed.py", "\tif x:\t\t\t\t\t# look nice") contains( - "out/tabbed/tabbed_py.html", + "out/tabbed_py.html", '> <span class="key">if</span> ' '<span class="nam">x</span><span class="op">:</span>' ' ' '<span class="com"># look nice</span>' ) - doesnt_contain("out/tabbed/tabbed_py.html", "\t") + doesnt_contain("out/tabbed_py.html", "\t") def test_unicode(self): - self.output_dir("out/unicode") + self.make_file("unicode.py", """\ + # -*- coding: utf-8 -*- + # A Python source file with exotic characters. - with change_dir("src"): - # pylint: disable=import-error, redefined-builtin - cov = coverage.Coverage() - cov.start() - import unicode # pragma: nested - cov.stop() # pragma: nested - cov.html_report(unicode, directory="../out/unicode") + upside_down = "ʎd˙ǝbɐɹǝʌoɔ" + surrogate = "db40,dd00: x󠄀" + """) + + # pylint: disable=import-error, redefined-builtin + cov = coverage.Coverage() + cov.start() + import unicode # pragma: nested + cov.stop() # pragma: nested + cov.html_report(unicode, directory="out") - compare_html("gold_unicode", "out/unicode") + compare_html("out", gold_path("html/gold_unicode")) contains( - "out/unicode/unicode_py.html", + "out/unicode_py.html", '<span class="str">"ʎd˙ǝbɐɹǝʌoɔ"</span>', ) contains_any( - "out/unicode/unicode_py.html", + "out/unicode_py.html", '<span class="str">"db40,dd00: x��"</span>', '<span class="str">"db40,dd00: x󠄀"</span>', ) diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 0987e41a..04eea3df 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -8,6 +8,7 @@ import os.path import coverage from coverage import env from coverage.backward import StringIO +from coverage.data import line_counts from coverage.control import Plugins from coverage.misc import CoverageException @@ -189,7 +190,8 @@ class PluginTest(CoverageTest): cov = coverage.Coverage(debug=["sys"]) cov._debug_file = debug_out cov.set_option("run:plugins", ["plugin_sys_info"]) - cov.load() + cov.start() + cov.stop() out_lines = [line.strip() for line in debug_out.getvalue().splitlines()] if env.C_TRACER: @@ -218,7 +220,8 @@ class PluginTest(CoverageTest): cov = coverage.Coverage(debug=["sys"]) cov._debug_file = debug_out cov.set_option("run:plugins", ["plugin_no_sys_info"]) - cov.load() + cov.start() + cov.stop() out_lines = [line.strip() for line in debug_out.getvalue().splitlines()] self.assertIn('plugins.file_tracers: -none-', out_lines) @@ -369,19 +372,19 @@ class GoodFileTracerTest(FileTracerTest): _, statements, missing, _ = cov.analysis("foo_7.html") self.assertEqual(statements, [1, 2, 3, 4, 5, 6, 7]) self.assertEqual(missing, [1, 2, 3, 6, 7]) - self.assertIn("foo_7.html", cov.get_data().line_counts()) + self.assertIn("foo_7.html", line_counts(cov.get_data())) _, statements, missing, _ = cov.analysis("bar_4.html") self.assertEqual(statements, [1, 2, 3, 4]) self.assertEqual(missing, [1, 4]) - self.assertIn("bar_4.html", cov.get_data().line_counts()) + self.assertIn("bar_4.html", line_counts(cov.get_data())) - self.assertNotIn("quux_5.html", cov.get_data().line_counts()) + self.assertNotIn("quux_5.html", line_counts(cov.get_data())) _, statements, missing, _ = cov.analysis("uni_3.html") self.assertEqual(statements, [1, 2, 3]) self.assertEqual(missing, [1]) - self.assertIn("uni_3.html", cov.get_data().line_counts()) + self.assertIn("uni_3.html", line_counts(cov.get_data())) def test_plugin2_with_branch(self): self.make_render_and_caller() diff --git a/tests/test_process.py b/tests/test_process.py index 1d277149..49919b0f 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -16,6 +16,7 @@ import pytest import coverage from coverage import env, CoverageData +from coverage.data import line_counts from coverage.misc import output_encoding from tests.coveragetest import CoverageTest @@ -90,8 +91,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) # Running combine again should fail, because there are no parallel data # files to combine. @@ -101,8 +102,8 @@ class ProcessTest(CoverageTest): # And the originally combined data is still there. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) def test_combine_parallel_data_with_a_corrupt_file(self): self.make_b_or_c_py() @@ -126,8 +127,13 @@ class ProcessTest(CoverageTest): self.assert_exists(".coverage") self.assert_exists(".coverage.bad") warning_regex = ( + r"(" # JSON message: r"Coverage.py warning: Couldn't read data from '.*\.coverage\.bad': " r"CoverageException: Doesn't seem to be a coverage\.py data file" + r"|" # SQL message: + r"Coverage.py warning: Couldn't use data file '.*\.coverage\.bad': " + r"file is encrypted or is not a database" + r")" ) self.assertRegex(out, warning_regex) @@ -137,8 +143,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) def test_combine_no_usable_files(self): # https://bitbucket.org/ned/coveragepy/issues/629/multiple-use-of-combine-leads-to-empty @@ -159,8 +165,14 @@ class ProcessTest(CoverageTest): for n in "12": self.assert_exists(".coverage.bad{0}".format(n)) warning_regex = ( + r"(" # JSON message: r"Coverage.py warning: Couldn't read data from '.*\.coverage\.bad{0}': " - r"CoverageException: Doesn't seem to be a coverage\.py data file".format(n) + r"CoverageException: Doesn't seem to be a coverage\.py data file" + r"|" # SQL message: + r"Coverage.py warning: Couldn't use data file '.*\.coverage.bad{0}': " + r"file is encrypted or is not a database" + r")" + .format(n) ) self.assertRegex(out, warning_regex) self.assertRegex(out, r"No usable data files") @@ -172,8 +184,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has 6 lines # executed (we only did b, not c). data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 6) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 6) def test_combine_parallel_data_in_two_steps(self): self.make_b_or_c_py() @@ -203,8 +215,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) def test_combine_parallel_data_no_append(self): self.make_b_or_c_py() @@ -235,8 +247,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has only 7 lines # because we didn't keep the data from running b. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 7) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 7) def test_append_data(self): self.make_b_or_c_py() @@ -254,8 +266,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) def test_append_data_with_different_file(self): self.make_b_or_c_py() @@ -277,9 +289,9 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. - data = coverage.CoverageData() - data.read_file(".mycovdata") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data = coverage.CoverageData(".mycovdata") + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) def test_append_can_create_a_data_file(self): self.make_b_or_c_py() @@ -292,8 +304,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has only 6 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 6) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 6) def test_combine_with_rc(self): self.make_b_or_c_py() @@ -325,8 +337,8 @@ class ProcessTest(CoverageTest): # Read the coverage file and see that b_or_c.py has all 8 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['b_or_c.py'], 8) + data.read() + self.assertEqual(line_counts(data)['b_or_c.py'], 8) # Reporting should still work even with the .rc file out = self.run_command("coverage report") @@ -379,8 +391,8 @@ class ProcessTest(CoverageTest): # Read the coverage data file and see that the two different x.py # files have been combined together. data = coverage.CoverageData() - data.read_file(".coverage") - summary = data.line_counts(fullpath=True) + data.read() + summary = line_counts(data, fullpath=True) self.assertEqual(len(summary), 1) actual = os.path.normcase(os.path.abspath(list(summary.keys())[0])) expected = os.path.normcase(os.path.abspath('src/x.py')) @@ -503,6 +515,8 @@ class ProcessTest(CoverageTest): def test_fork(self): if not hasattr(os, 'fork'): self.skipTest("Can't test os.fork since it doesn't exist.") + # See https://nedbatchelder.com/blog/201808/sqlite_data_storage_for_coveragepy.html + self.skip_unless_data_storage_is_json() self.make_file("fork.py", """\ import os @@ -543,8 +557,8 @@ class ProcessTest(CoverageTest): self.assert_file_count(".coverage.*", 0) data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['fork.py'], 9) + data.read() + self.assertEqual(line_counts(data)['fork.py'], 9) def test_warnings_during_reporting(self): # While fixing issue #224, the warnings were being printed far too @@ -641,6 +655,8 @@ class ProcessTest(CoverageTest): if env.PYPY and env.PY3 and env.PYPYVERSION[:3] == (5, 10, 0): # pragma: obscure # https://bitbucket.org/pypy/pypy/issues/2729/pypy3-510-incorrectly-decodes-astral-plane self.skipTest("Avoid incorrect decoding astral plane JSON chars") + self.skip_unless_data_storage_is_json() + self.make_file(".coveragerc", """\ [run] data_file = mydata.dat @@ -649,8 +665,8 @@ class ProcessTest(CoverageTest): self.make_file("simple.py", """print('hello')""") self.run_command("coverage run simple.py") - data = CoverageData() - data.read_file("mydata.dat") + data = CoverageData("mydata.dat") + data.read() infos = data.run_infos() self.assertEqual(len(infos), 1) expected = u"These are musical notes: ♫𝅗𝅥♩" @@ -680,11 +696,11 @@ class ProcessTest(CoverageTest): out = self.run_command("python -m coverage run -L getenv.py") self.assertEqual(out, "FOOEY == BOO\n") data = coverage.CoverageData() - data.read_file(".coverage") + data.read() # The actual number of executed lines in os.py when it's # imported is 120 or so. Just running os.getenv executes # about 5. - self.assertGreater(data.line_counts()['os.py'], 50) + self.assertGreater(line_counts(data)['os.py'], 50) def test_lang_c(self): if env.JYTHON: @@ -910,8 +926,8 @@ class ExcepthookTest(CoverageTest): # Read the coverage file and see that excepthook.py has 7 lines # executed. data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['excepthook.py'], 7) + data.read() + self.assertEqual(line_counts(data)['excepthook.py'], 7) def test_excepthook_exit(self): if env.PYPY or env.JYTHON: @@ -1239,9 +1255,9 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): # An existing data file should not be read when a subprocess gets # measured automatically. Create the data file here with bogus data in # it. - data = coverage.CoverageData() + data = coverage.CoverageData(".mycovdata") data.add_lines({os.path.abspath('sub.py'): dict.fromkeys(range(100))}) - data.write_file(".mycovdata") + data.write() self.make_file("coverage.ini", """\ [run] @@ -1255,9 +1271,9 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): # Read the data from .coverage self.assert_exists(".mycovdata") - data = coverage.CoverageData() - data.read_file(".mycovdata") - self.assertEqual(data.line_counts()['sub.py'], 3) + data = coverage.CoverageData(".mycovdata") + data.read() + self.assertEqual(line_counts(data)['sub.py'], 3) def test_subprocess_with_pth_files_and_parallel(self): # pragma: no metacov # https://bitbucket.org/ned/coveragepy/issues/492/subprocess-coverage-strange-detection-of @@ -1280,8 +1296,8 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest): # assert that the combined .coverage data file is correct self.assert_exists(".coverage") data = coverage.CoverageData() - data.read_file(".coverage") - self.assertEqual(data.line_counts()['sub.py'], 3) + data.read() + self.assertEqual(line_counts(data)['sub.py'], 3) # assert that there are *no* extra data files left over after a combine data_files = glob.glob(os.getcwd() + '/.coverage*') @@ -1370,8 +1386,8 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest): # Read the data from .coverage self.assert_exists(".coverage") data = coverage.CoverageData() - data.read_file(".coverage") - summary = data.line_counts() + data.read() + summary = line_counts(data) print(summary) self.assertEqual(summary[source + '.py'], 3) self.assertEqual(len(summary), 1) diff --git a/tests/test_summary.py b/tests/test_summary.py index b2895370..980fd3d4 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -161,7 +161,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # Read the data written, to see that the right files have been omitted from running. covdata = CoverageData() - covdata.read_file(".coverage") + covdata.read() files = [os.path.basename(p) for p in covdata.measured_files()] self.assertIn("covmod1.py", files) self.assertNotIn("covmodzip1.py", files) diff --git a/tests/test_xml.py b/tests/test_xml.py index acb82a48..65c1a48b 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -13,8 +13,7 @@ from coverage.backward import import_local_file 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.goldtest import change_dir, compare, gold_path from tests.helpers import re_line, re_lines @@ -310,25 +309,26 @@ def clean(text, scrub=None): return text -class XmlGoldTest(CoverageGoldTest): +class XmlGoldTest(CoverageTest): """Tests of XML reporting that use gold files.""" - # TODO: this should move out of html. - root_dir = 'tests/farm/html' - def test_a_xml_1(self): - self.output_dir("out/xml_1") + self.make_file("a.py", """\ + if 1 < 2: + # Needed a < to look at HTML entities. + a = 3 + else: + a = 4 + """) - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage() - cov.start() - import a # pragma: nested - cov.stop() # pragma: nested - cov.xml_report(a, outfile="../out/xml_1/coverage.xml") - source_path = coverage.files.relative_directory().rstrip(r"\/") + cov = coverage.Coverage() + cov.start() + import a # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.xml_report(a, outfile="coverage.xml") + source_path = coverage.files.relative_directory().rstrip(r"\/") - compare("gold_x_xml", "out/xml_1", scrubs=[ + compare(".", gold_path("html/gold_x_xml"), left_extra=True, scrubs=[ (r' timestamp="\d+"', ' timestamp="TIMESTAMP"'), (r' version="[-.\w]+"', ' version="VERSION"'), (r'<source>\s*.*?\s*</source>', '<source>%s</source>' % source_path), @@ -336,18 +336,28 @@ class XmlGoldTest(CoverageGoldTest): ]) def test_a_xml_2(self): - self.output_dir("out/xml_2") - - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(config_file="run_a_xml_2.ini") - cov.start() - import a # pragma: nested - cov.stop() # pragma: nested - cov.xml_report(a) - source_path = coverage.files.relative_directory().rstrip(r"\/") - - compare("gold_x_xml", "out/xml_2", scrubs=[ + self.make_file("a.py", """\ + if 1 < 2: + # Needed a < to look at HTML entities. + a = 3 + else: + a = 4 + """) + + self.make_file("run_a_xml_2.ini", """\ + # Put all the XML output in xml_2 + [xml] + output = xml_2/coverage.xml + """) + + cov = coverage.Coverage(config_file="run_a_xml_2.ini") + cov.start() + import a # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.xml_report(a) + source_path = coverage.files.relative_directory().rstrip(r"\/") + + compare("xml_2", gold_path("html/gold_x_xml"), scrubs=[ (r' timestamp="\d+"', ' timestamp="TIMESTAMP"'), (r' version="[-.\w]+"', ' version="VERSION"'), (r'<source>\s*.*?\s*</source>', '<source>%s</source>' % source_path), @@ -355,18 +365,24 @@ class XmlGoldTest(CoverageGoldTest): ]) def test_y_xml_branch(self): - self.output_dir("out/y_xml_branch") - - with change_dir("src"): - # pylint: disable=import-error - cov = coverage.Coverage(branch=True) - cov.start() - import y # pragma: nested - cov.stop() # pragma: nested - cov.xml_report(y, outfile="../out/y_xml_branch/coverage.xml") - source_path = coverage.files.relative_directory().rstrip(r"\/") - - compare("gold_y_xml_branch", "out/y_xml_branch", scrubs=[ + self.make_file("y.py", """\ + def choice(x): + if x < 2: + return 3 + else: + return 4 + + assert choice(1) == 3 + """) + + cov = coverage.Coverage(branch=True) + cov.start() + import y # pragma: nested # pylint: disable=import-error + cov.stop() # pragma: nested + cov.xml_report(y, outfile="y_xml_branch/coverage.xml") + source_path = coverage.files.relative_directory().rstrip(r"\/") + + compare("y_xml_branch", gold_path("html/gold_y_xml_branch"), scrubs=[ (r' timestamp="\d+"', ' timestamp="TIMESTAMP"'), (r' version="[-.\w]+"', ' version="VERSION"'), (r'<source>\s*.*?\s*</source>', '<source>%s</source>' % source_path), @@ -15,10 +15,6 @@ deps = -rrequirements/pytest.pip pip==18.0 setuptools==40.0.0 - mock==2.0.0 - PyContracts==1.8.3 - unittest-mixins==1.4 - #-e/Users/ned/unittest_mixins # gevent 1.3 causes a failure: https://bitbucket.org/ned/coveragepy/issues/663/gevent-132-on-windows-fails py{27,34,35,36}: gevent==1.2.2 py{27,34,35,36,37}: eventlet==0.24.1 @@ -89,8 +85,9 @@ commands = python -m pylint --notes= {env:LINTABLE} [travis] +#2.7: py27, lint python = - 2.7: py27, lint + 2.7: py27 3.4: py34 3.5: py35 3.6: py36 |