class TestTreeprocessor(Treeprocessor): """Treats a series of code fragments in a markdown document as a doctest. Moreover, the results of the doctest are embedded in the resulting document. XML fragments are assumed to be LOM fragments, and are transformed into MLR by a Converter. N3 fragments are assumed to be MLR fragments. Each triple in a N3 fragment is required to be found in the MLR generated from the previous LOM fragment. Some N3 fragments are forbidden: triples from such fragments found in the MLR generated from the previous LOM fragment AND not in the previous (required) N3 fragment constitute an error. The comparison uses the GraphTester. """ def __init__(self, md, buttons, hide_eg, delete_eg): self.graph_tester = GraphTester() self.buttons = buttons self.hide_eg = hide_eg self.delete_eg = delete_eg def remove_namespace(self, n3): lines = n3.split("\n") lines = [l for l in lines if l and l[0] != '@'] return "\n".join(lines) def make_response(self, graphs): assert len(graphs) in range(2, 4), "%d sections of code" % (len(graphs),) errors = self.graph_tester.test_graphs(*graphs) if errors: pass def run(self, root): elements = list(root) # should be an iterator, but 2.6 getiterator vs 2.7 iter. root.clear() target = root graphs = [] error = False example_num = 0 for element in elements: if HEADER_R.match(element.tag): if graphs and not error: response = self.make_response(graphs) if response: target.append(response) target = root graphs = [] error = False print(" " * int(element.tag[1]) + element.text) elif element.tag == 'pre': sub = list(element) assert len(sub) == 1 code_el = sub[0] assert code_el.tag == 'code' format, code, args = splitcode(code_el.text) code_el.text = ":::%s\n%s" % (format, code) # remove args divclasses = [format] if args == 'forbidden': divclasses.append(args) if format.lower() == 'n3': divclasses.append('mlr') subdiv = etree.Element('div', {'class': ' '.join(divclasses)}) subdiv.append(element) element = subdiv if target is root: example_num += 1 if self.buttons: button = etree.Element('button', {'onclick': "$('#eg%d').toggle();" % (example_num,)}) button.text = 'Example' root.append(button) divattr = {"class": "example", 'id': 'eg%d' % (example_num,)} if self.hide_eg: divattr['style'] = 'display:none' div = etree.Element('div', divattr) if not self.delete_eg: root.append(div) target = div if format.lower() == 'xml': try: self.graph_tester.set_lom(code) except Exception as e: target.append(element) p2 = etree.Element('pre', {"class": "error"}) tr = etree.Element('code') p2.append(tr) tr.text = ":::Python Traceback\n" + traceback.format_exc() element = p2 print('*', e) error = True elif format.lower() == 'n3': try: graph, errors = self.graph_tester.test_n3(code, args) if errors: target.append(element) diverrors = etree.Element('div', {"class": "error"}) p = etree.Element('p') p.text = "Erreur. Obtenu: " diverrors.append(p) pre = etree.Element('pre') diverrors.append(pre) graph_e = etree.Element('code') pre.append(graph_e) result = graph.serialize(format='n3', encoding='utf-8') graph_e.text = ':::N3\n' + self.remove_namespace(result).decode('utf-8') for err_type, error in errors: p = etree.Element('p') error = tuple(map(stringify_error_element, error)) if err_type == GraphTester.MISSING: p.text = u"Il manque < %s %s %s >." % error elif err_type == GraphTester.UNEXPECTED: p.text = u"< %s %s %s < est présent et ne devrait pas l'être." % error print('*', p.text) diverrors.append(p) element = diverrors except Exception as e: target.append(element) p2 = etree.Element('pre', {"class": "error"}) tr = etree.Element('code') p2.append(tr) tr.text = ":::Python Traceback\n" + traceback.format_exc() element = p2 print('*', e) error = True target.append(element) if graphs and not error: response = self.make_response(graphs) if response: target.append(response) return root
def __init__(self, md, buttons, hide_eg, delete_eg): self.graph_tester = GraphTester() self.buttons = buttons self.hide_eg = hide_eg self.delete_eg = delete_eg
def setupClass(self): self.graphtester = GraphTester()
class testGraphComparison(unittest.TestCase): @classmethod def setupClass(self): self.graphtester = GraphTester() def parse(self, source): return Graph().parse(data=N3_PREFIXES + source, format="n3") def test_find_missing(self): errors = self.graphtester.find_missing( self.parse(''' <http://example.com> a mlr1:RC0002 ; mlr2:DES0100 "Titre" ; mlr2:DES0200 "Auteur" . '''), self.parse(''' <http://example.com> a mlr1:RC0002. ''')) assert len(errors) == 2 def test_find_missing_on_blank(self): errors = self.graphtester.find_missing( self.parse(''' <http://example.com> a mlr1:RC0002 ; mlr5:DES1300 [ a mlr5:RC0001; mlr5:DES0200 "Commentaire" ] . '''), self.parse(''' <http://example.com> a mlr1:RC0002 ; mlr5:DES1300 [ a mlr5:RC0001 ] . ''')) assert len(errors) == 1 error = errors[0] print(error) assert error[2] == Literal(u"Commentaire") def test_find_missing_on_uuid(self): errors = self.graphtester.find_missing( self.parse(''' <urn:uuid:10000000-0000-0000-0000-000000000001> a mlr1:RC0002. <urn:uuid:10000000-0000-0000-0000-000000000001> mlr5:DES1700 <urn:uuid:10000000-0000-0000-0000-000000000002>. '''), self.parse(''' <urn:uuid:75411ac2-d077-11e1-b25b-c8bcc8f0abdf> a mlr1:RC0002. <urn:uuid:75411ac2-d077-11e1-b25b-c8bcc8f0abdf> mlr5:DES1700 <urn:uuid:75411ac2-d077-11e1-b25b-c8bcc8f0abcd> . ''')) assert len(errors) == 0, errors def test_find_unexpected(self): obtained = self.parse(''' <http://example.com> a mlr1:RC0002 ; mlr2:DES0100 "Titre" . ''') expected = self.parse('<http://example.com> a mlr1:RC0002 .') forbidden = self.parse(''' <http://example.com> a mlr1:RC0002 ; mlr2:DES0100 "Titre" . ''') errors = self.graphtester.find_missing(expected, obtained) assert not errors errors = self.graphtester.find_forbidden(forbidden, obtained) assert len(errors) == 1 error = errors[0] assert error[2] == Literal(u"Titre") def test_identify_blanks(self): g1 = Graph() g1.bind("mlr1", MLR1_NS) s1 = BNode() g1.add((s1, RDF.type, MLR1["RC0002"])) g2 = Graph() g2.bind("mlr1", MLR1_NS) s2 = BNode() g2.add((s2, RDF.type, MLR1["RC0002"])) c = GraphCorrespondence(g1, g2) c.identify() map = c.blank_map assert map == {s1: s2}
"""Integrates MLR doctests in :file:`rationale.md` as unit tests""" import re import markdown from lom2mlr.validate.graph_comparison import GraphTester from lom2mlr.util import splitcode HEADER_R = re.compile(r'^h[1-9]$', re.I) graphtester = GraphTester() def t_function(data, title): assert len(data) > 1, data assert data[0][0].lower() == 'xml', data for (format, code, args) in data: graph, errors = graphtester.process_line( format, code, args) assert not errors, title + ' ' + repr(errors) def test_document(): m = markdown.Markdown() data = open('rationale.md').read().decode('utf-8') root = m.parser.parseDocument(data.split('\n')).getroot() data = [] title = '' for element in root.getiterator(): if HEADER_R.match(element.tag):