Source code for timApp.tests.unit.test_documentparser

import random
import unittest

from timApp.document.documentparser import DocumentParser
from timApp.document.documentparseroptions import DocumentParserOptions
from timApp.document.documentwriter import DocumentWriter
from timApp.document.exceptions import ValidationException


[docs]class DocumentParserTest(unittest.TestCase):
[docs] def test_parsing(self): doc_text = """ ``` {plugin=csPlugin} code code ``` text1 text2 ``` {plugin=mmcq} code2 ``` # Header 1 headerpar 1 headerpar 2 ``` normal code ``` # Header 2 headerpar 3 headerpar 4 #- {.someClass} text 3 text 4 ``` {atom=true} # Test1 # Test2 # Test3 ``` ``` code ``` test # Test {a=b} ```` #- {rd=x rp=y} ``` {rp=x rd=y} ``` ```` ```` test ```` ```cs var a = 1 + 1; ``` ```js {.someClass} var a = 1 + 1; ``` """.strip() dp = DocumentParser(doc_text) result = dp.get_blocks() expected = [ { "md": "```\ncode\n\ncode\n```", "attrs": {"plugin": "csPlugin"}, "type": "code", }, {"md": "text1\n\ntext2", "type": "autonormal", "attrs": {}}, {"md": "```\ncode2\n```", "attrs": {"plugin": "mmcq"}, "type": "code"}, { "md": "# Header 1\n\nheaderpar 1\n\nheaderpar 2", "type": "header", "attrs": {}, }, {"md": "```\nnormal code\n```", "type": "code", "attrs": {}}, { "md": "# Header 2\n\nheaderpar 3\n\nheaderpar 4", "type": "header", "attrs": {}, }, { "md": "text 3\n\n\ntext 4", "attrs": {"classes": ["someClass"]}, "type": "normal", }, {"md": "# Test1\n\n# Test2\n\n# Test3", "type": "atom", "attrs": {}}, {"md": "```\ncode\n```", "type": "code", "attrs": {}}, {"md": "test", "type": "autonormal", "attrs": {}}, {"type": "header", "attrs": {"a": "b"}, "md": "# Test"}, { "md": "````\n#- {rd=x rp=y}\n\n``` {rp=x rd=y}\n```\n\n````", "type": "code", "attrs": {}, }, {"md": "````\ntest\n````", "type": "code", "attrs": {}}, { "md": "```cs\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"code_lang": "cs"}, }, { "md": "```js\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"classes": ["someClass"], "code_lang": "js"}, }, ] self.assertListEqual(expected, result) exported = DocumentWriter(result).get_text() self.assertListEqual(expected, DocumentParser(exported).get_blocks()) random.seed(0) dp.add_missing_attributes() self.assertListEqual( [ {"id": "SoMUq2gZwvpI"}, {"id": "WORjZumBVWdm"}, {"id": "w8i8M6DPgWyR"}, {"id": "JPCV9j6K4VSg"}, {"id": "Hluz6mrkDEWe"}, {"id": "dZzusTxg3PW5"}, {"id": "zW05KRpJQOG9"}, {"id": "E0DvQTlfKkJd"}, {"id": "T4cWAefPZ9Po"}, {"id": "ys55kUwXv6jY"}, {"id": "ziJ7zlQXydZE"}, {"id": "PCzBis5CPokx"}, {"id": "AfibcQb2DGgM"}, {"id": "u45HM8U9X2RQ"}, {"id": "5VIXRyHpRJx0"}, ], [{"id": block["id"]} for block in dp.get_blocks()], ) self.assertListEqual( [ {"t": "LTB4NGQwMTZhODI="}, {"t": "MHg3ZjUxNmRhYw=="}, {"t": "MHgyZTE2OTQzOA=="}, {"t": "LTB4MjQzZTM5MmU="}, {"t": "LTB4MWIyNGU1NzI="}, {"t": "LTB4MzI5Y2Y0ZWM="}, {"t": "MHgzNGFiZTAwYw=="}, {"t": "LTB4NTZiNGY3ZGU="}, {"t": "MHg3ZDY2ZjA3MQ=="}, {"t": "MHgzMDYzZmNkYg=="}, {"t": "MHg3NjQzNzAyYg=="}, {"t": "LTB4MmJhMWVlZGI="}, {"t": "MHgyNjJlNzU5OQ=="}, {"t": "MHg3YzE0OGE4"}, {"t": "MHgxNmM0MjFjMA=="}, ], [{"t": block["t"]} for block in dp.get_blocks()], ) dp.validate_structure().raise_if_has_any_issues() self.assertEqual([], DocumentParser("").get_blocks()) self.assertEqual("", DocumentWriter([]).get_text()) self.assertEqual( '#- {a="b"}\n', DocumentWriter([{"md": "", "attrs": {"a": "b"}}]).get_text() ) self.assertListEqual( [{"md": "```\n```", "type": "code", "attrs": {}}], DocumentParser("```").get_blocks(), ) result = DocumentParser( doc_text, DocumentParserOptions.break_on_empty_lines() ).get_blocks() self.assertListEqual( [ { "md": "```\ncode\n\ncode\n```", "attrs": {"plugin": "csPlugin"}, "type": "code", }, {"md": "text1", "type": "autonormal", "attrs": {}}, {"md": "text2", "type": "autonormal", "attrs": {}}, {"md": "```\ncode2\n```", "attrs": {"plugin": "mmcq"}, "type": "code"}, {"md": "# Header 1", "type": "header", "attrs": {}}, {"md": "headerpar 1", "type": "autonormal", "attrs": {}}, {"md": "headerpar 2", "type": "autonormal", "attrs": {}}, {"md": "```\nnormal code\n```", "type": "code", "attrs": {}}, {"md": "# Header 2", "type": "header", "attrs": {}}, {"md": "headerpar 3", "type": "autonormal", "attrs": {}}, {"md": "headerpar 4", "type": "autonormal", "attrs": {}}, {"md": "text 3", "attrs": {"classes": ["someClass"]}, "type": "normal"}, {"md": "text 4", "type": "autonormal", "attrs": {}}, {"md": "# Test1\n\n# Test2\n\n# Test3", "type": "atom", "attrs": {}}, {"md": "```\ncode\n```", "type": "code", "attrs": {}}, {"md": "test", "type": "autonormal", "attrs": {}}, {"md": "# Test", "type": "header", "attrs": {"a": "b"}}, { "attrs": {}, "type": "code", "md": "````\n#- {rd=x rp=y}\n\n``` {rp=x rd=y}\n```\n\n````", }, {"attrs": {}, "md": "````\ntest\n````", "type": "code"}, { "md": "```cs\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"code_lang": "cs"}, }, { "md": "```js\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"classes": ["someClass"], "code_lang": "js"}, }, ], result, ) result = DocumentParser( doc_text, DocumentParserOptions.single_paragraph() ).get_blocks() expected = [ { "md": "```\ncode\n\ncode\n```", "attrs": {"plugin": "csPlugin"}, "type": "code", }, {"md": "text1\n\ntext2", "type": "autonormal", "attrs": {}}, {"md": "```\ncode2\n```", "attrs": {"plugin": "mmcq"}, "type": "code"}, { "md": "# Header 1\n\nheaderpar 1\n\nheaderpar 2\n\n```\nnormal code\n```\n\n" "# Header 2\n\nheaderpar 3\n\nheaderpar 4", "type": "header", "attrs": {}, }, { "md": "text 3\n\n\ntext 4", "attrs": {"classes": ["someClass"]}, "type": "normal", }, {"md": "# Test1\n\n# Test2\n\n# Test3", "type": "atom", "attrs": {}}, {"md": "```\ncode\n```\n\ntest", "type": "code", "attrs": {}}, { "attrs": {"a": "b"}, "md": "# Test\n" "\n" "````\n" "#- {rd=x rp=y}" "\n" "\n" "``` {rp=x rd=y}" "\n" "```\n" "\n" "````\n" "\n" "````\n" "test\n" "````", "type": "header", }, { "md": "```cs\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"code_lang": "cs"}, }, { "md": "```js\nvar a = 1 + 1;\n```", "type": "code", "attrs": {"classes": ["someClass"], "code_lang": "js"}, }, ] self.assertListEqual(expected, result) exported = DocumentWriter(result).get_text() # ignore 'type' because some of them are now 'atom' self.assertListEqual( [{"md": p["md"], "attrs": p["attrs"]} for p in expected], [ {"md": p["md"], "attrs": p["attrs"]} for p in DocumentParser(exported).get_blocks() ], ) self.assertListEqual( [{"attrs": {}, "type": "code", "md": "```\nasd\n```"}], DocumentParser("```\nasd").get_blocks(), ) self.assertListEqual( [{"attrs": {}, "type": "code", "md": "```\n```"}], DocumentParser("```").get_blocks(), )
[docs] def test_validation(self): failures = [ """ #- {id=SoMUq2gZwvpI} #- {id=SoMUq2gZwvpI} """, """ #- {area=test} """, """ #- {area_end=test} """, """ #- {area=test} #- {area_end=test} #- {area=test} #- {area_end=test} """, """ #- {area=test .some} #- {area=test2 .some} #- {area_end=test} #- {area_end=test2} """, """ #- {area=test area_end=test} """, # """ # - {#test} # - {#test} # """, """ #- {id=someinvalid} """, """ ``` ``` {a=b} """, ] oks = [ """ #- {area=test} #- {area_end=test} """, """ #- {area=test .some} #- {area=test2 .some} #- {area=test4 .some} #- {area_end=test4} #- {area_end=test2} #- {area=test3 .some} #- {area_end=test3} #- {area_end=test} """, """``` ``{a=b} """, "", ] for f in failures: with self.assertRaises(ValidationException, msg=f): DocumentParser(f).validate_structure().raise_if_has_any_issues() for o in oks: DocumentParser(o).validate_structure().raise_if_has_any_issues()
[docs] def test_incomplete_code(self): for text, expected in ( ("```\n``", "```\n```"), ("```\na", "```\na\n```"), ("```\n", "```\n```"), ("```", "```\n```"), ("````", "````\n````"), ("````\na", "````\na\n````"), ): result = DocumentParser( text, DocumentParserOptions.single_paragraph() ).get_blocks() self.assertEqual([{"attrs": {}, "md": expected, "type": "code"}], result) result.append({"attrs": {}, "md": "```\n```", "type": "code"}) exported = DocumentWriter(result).get_text() self.assertEqual(expected + "\n\n```\n```\n", exported) new_result = DocumentParser(exported).get_blocks() self.assertListEqual(result, new_result)