import py def pytest_addoption(parser): group = parser.addgroup("apigen options") group.addoption( '--apigen', action="store_true", dest="apigen", help="generate api documentation") group.addoption( '--apigenpath', action="store", dest="apigenpath", default="../apigen-output", type="string", help="path to apigen doc output location (relative to " "package root)") group.addoption( '--docpath', action='store', dest='docpath', default="doc", type='string', help="path to documentation location (relative from " "package root)") group.addoption( '--apigenscript', action='store', dest='apigenscript', default=None, type='string', help='path to script that contains apigen hooks for the project') group.addoption( '--apigen-nocapture', action='store_true', dest='apigen_nocapture', help='do not capture stdin/stdout/stderr on generating docs - ' 'mostly for debugging apigen itself') def pytest_configure(config): config.pluginmanager.register(OldstylePluginApigenPlugin()) class OldstylePluginApigenPlugin: def pytest_configure(self, config): if config.option.apigenscript: config.option.apigen = True if config.option.apigen: from apigen.tracer.tracer import Tracer from apigen.tracer.docstorage import DocStorage #pkgpath = py.path.local(config.args[0]) pkgpath = py.path.local(py.__file__).dirpath() self.pkgdir = pkgpath.pypkgpath() apigenscriptpath = config.option.apigenscript if not apigenscriptpath: apigenscriptpath = "apigen/build.py" apigenscriptpath = pkgpath.join(apigenscriptpath, abs=True) if not apigenscriptpath.check(file=True): raise config.Error('can not find apigen script: %s' % (apigenscriptpath,)) return apigenscript = apigenscriptpath.pyimport() if not hasattr(apigenscript, 'get_documentable_items'): raise NotImplementedError( "%r needs to provide get_documentable_items" %( apigenscriptpath,)) self.apigenscript = apigenscript pkgname, items = apigenscript.get_documentable_items(self.pkgdir) self.docstorage = DocStorage().from_dict( items, module_name=pkgname) self.tracer = Tracer(self.docstorage) def pytest_pyfunc_call(self, __multicall__, pyfuncitem): if hasattr(self, 'tracer'): self.tracer.start() try: return __call__.execute(firstresult=True) finally: self.tracer.end() def pytest_terminal_summary(self, terminalreporter): if hasattr(self, 'tracer'): tr = terminalreporter from apigen.tracer.docstorage import DocStorageAccessor terminalreporter.write_sep("=", "apigen: building documentation") assert hasattr(tr.config.option, 'apigenpath') capture = None if not tr.config.option.apigen_nocapture: capture = py.io.StdCaptureFD() try: self.apigenscript.build( tr.config, self.pkgdir, DocStorageAccessor(self.docstorage), capture) finally: if capture is not None: capture.reset() terminalreporter.write_line("apigen build completed") # # Plugin tests # pytest_plugins = "pytest_pytester" def test_functional_simple(testdir): sub = testdir.tmpdir.mkdir("test_simple") sub.join("__init__.py").write(py.code.Source(""" from py import initpkg initpkg(__name__, exportdefs={ 'simple.f': ('./test_simple.py', 'f',), }) """)) pyfile = sub.join("test_simple.py") pyfile.write(py.code.Source(""" def f(arg): pass def test_f(): f(42) """)) buildfile = testdir.tmpdir.join('apigen_build.py') buildfile.write(py.code.Source(''' from apigen.tool.htmlgen.build import build import test_simple as simple print simple def get_documentable_items(pkgdir): return 'simple', { 'simple.f': simple.f, } ''')) testdir.makepyfile(conftest="pytest_plugins='apigen'") testdir.plugins.append("pytest_apigen") result = testdir.runpytest( pyfile, "--apigen", "--apigenscript=%s" % ( testdir.tmpdir.join('apigen_build.py'),)) result.stdout.fnmatch_lines([ "*apigen: building documentation*", "apigen build completed", ])