Commit 673146f3 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

munge sys.path & sys.modules during coverage tests

To make coverage tests work, build to a build path and add it to
sys.path, remove tested modules before tests so that the import-time
code is included in coverage.
parent 9a30eb1c
Loading
Loading
Loading
Loading
+45 −5
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ from six import string_types, PY3
from itertools import product
from functools import wraps
from fnmatch import fnmatch
from pkg_resources import working_set, normalize_path
import contextlib
import importlib
import itertools
@@ -94,9 +95,9 @@ def coverage_report(modules, include=None, exclude=None, file=None):

	try:
		yield
	finally:
		sys.modules.clear()
		sys.modules.update(old_modules)
	except (SystemExit):
		modules = {sys.modules.get(m.__name__) for m in modules}
		modules.discard(None)

		cover.stop()
		cover.save()
@@ -106,6 +107,22 @@ def coverage_report(modules, include=None, exclude=None, file=None):
			if file.isatty():
				file.write("\nCoverage Report:\n================\n")
			cover.report(list(modules), include=include, omit=exclude, file=file)
	finally:
		sys.modules.clear()
		sys.modules.update(old_modules)


@contextlib.contextmanager
def additional_paths(*paths):
	old_path = sys.path
	sys.path = list(paths)
	sys.path.extend(old_path)
	working_set.__init__()
	try:
		yield
	finally:
		sys.path = old_path
		working_set.__init__()


def test_coverage_command(superclass, packages=None, include=None, exclude=None):
@@ -153,9 +170,32 @@ def test_coverage_command(superclass, packages=None, include=None, exclude=None)
			if not self.with_coverage:
				return super(test, self).run()

			with coverage_report(packages or self.distribution.packages,
			self.run_command('build')
			build = self.get_finalized_command('build')

			# == Copied from setuptools test command ==

			# Ensure metadata is up-to-date
			self.reinitialize_command('build_py', inplace=0)
			self.run_command('build_py')
			bpy_cmd = self.get_finalized_command("build_py")
			build_path = normalize_path(bpy_cmd.build_lib)

			# Build extensions
			self.reinitialize_command('egg_info', egg_base=build_path)
			self.run_command('egg_info')

			self.reinitialize_command('build_ext', inplace=0)
			self.run_command('build_ext')

			ei_cmd = self.get_finalized_command("egg_info")

			# ==

			with additional_paths(ei_cmd.egg_base), coverage_report(
					packages or self.distribution.packages,
					include=include, exclude=exclude,
					file=self.coverage_report):
				super(test, self).run()
				super(test, self).run_tests()

	return test