PKL&!bbpytest_markdown/__init__.py''' A py.test plugin that runs tests its found in your Markdown files. ''' __version__ = '0.0.5' PKLSmH pytest_markdown/plugin.pyimport imp import CommonMark import pytest from _pytest.python import Module class MarkdownItem(Module): def __init__(self, name, file, code, nodeid=None): self._code_obj = imp.new_module(name) exec(code, self._code_obj.__dict__) super().__init__(name, file, nodeid=nodeid) def _getobj(self): return self._code_obj def collect_literals_from_children(token): literals = [] stack = [token.first_child] while stack: cur = stack.pop() if cur.literal: literals.append(cur.literal) if cur.nxt: stack.append(cur.nxt) if cur.first_child: stack.append(cur.first_child) return ''.join(literals) class MarkdownCollector(object): def __init__(self, item): super().__init__() self.item = item self.ast = CommonMark.Parser().parse(self.item.fspath.open().read()) self.stack = [(0, self.item, self.item.name,)] self.collected = [] def collect(self): self.stack = [(0, self.item, self.item.name,)] self.collected = [] walker = self.ast.walker() event = walker.nxt() while event is not None: if not event['entering']: event = walker.nxt() continue func = 'visit_' + event['node'].t if hasattr(self, func): getattr(self, func)(event['node']) event = walker.nxt() return self.collected def visit_heading(self, token): while self.stack[-1][0] >= token.level: self.stack.pop() name = collect_literals_from_children(token).lower().replace(' ', '-') nodeid = '::'.join(s[2] for s in self.stack) + '::' + name self.stack.append(( token.level, pytest.Item(name, self.stack[-1][1], nodeid=nodeid), name )) def visit_code_block(self, token): if token.info != 'python': return output = token.literal if output.startswith('\n'): return '' name = f'line_{token.sourcepos[0][0]}' if output.lower().strip().startswith('# conftest.py\n'): nodeid = self.stack[-1][1].nodeid else: nodeid = self.stack[-1][1].nodeid + '::' + name mi = MarkdownItem( name, self.stack[-1][1], output, nodeid=nodeid ) self.collected.append(mi) return '' class MarkdownFile(pytest.File): def collect(self): for item in MarkdownCollector(self).collect(): yield item def pytest_collect_file(parent, path): if path.ext == '.md': return MarkdownFile(path, parent) PK!H-1B#,0pytest_markdown-0.0.5.dist-info/entry_points.txt.,I-.14M,N/ϳz9y\\PK!HNO%pytest_markdown-0.0.5.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,zd&Y)r$[)T&UrPK!Hk\{(pytest_markdown-0.0.5.dist-info/METADATA]S]o@|XW| KBҤU@<ѫnHg/q%{vnwvn< +d Wd 8XSKhk#e,mK}fDF P=E'ԪC/Ϥ1mQBDIztSG{5Qͭ*x>ueq}MbhpCtn@rRub\Q Xqsʡ{~Żlt^9 hB-O 'B^ y 7ؑ̅e!z( x9\'{GZ+4My/y%I}"U0=lTtx_Ue"YF͔|)iM&Xd/f?(B+7[; &գk%[/gsF}Rؒ XCDߪDZims\8T!u>ԋ醹Ż>=Abmþb0D],2"HG!)/Ӻ"%Mb0DS&|Yj}>o'G`eV||© |?9x6/M09ƻ8 ->ڎ**/>kUU϶ F $cgyl/ 5 @^pmw:_PKL&!bbpytest_markdown/__init__.pyPKLSmH pytest_markdown/plugin.pyPK!H-1B#,0 pytest_markdown-0.0.5.dist-info/entry_points.txtPK!HNO% pytest_markdown-0.0.5.dist-info/WHEELPK!Hk\{( pytest_markdown-0.0.5.dist-info/METADATAPK!H:S3&pytest_markdown-0.0.5.dist-info/RECORDPK\