test_parser_json.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. """
  2. This module supplies basic tests for the odml.dict_parser.DictReader
  3. reading from json files.
  4. """
  5. import json
  6. import os
  7. import shutil
  8. import unittest
  9. from odml.tools import dict_parser
  10. from odml.tools.parser_utils import ParserException, InvalidVersionException
  11. from .util import create_test_dir, TEST_RESOURCES_DIR as RES_DIR
  12. _INVALID_ATTRIBUTE_HANDLING_DOC = """
  13. {
  14. "Document": {
  15. "id": "6af2a3ec-9f3a-42d6-a59d-95f3ccbaa383",
  16. "%s": "i_do_not_exist_on_doc_level",
  17. "sections": [
  18. {
  19. "id": "51f3c79c-a7d7-471e-be16-e085caa851fb",
  20. "%s": "i_do_not_exist_on_sec_level",
  21. "type": "test",
  22. "name": "sec",
  23. "sections": [],
  24. "properties": [
  25. {
  26. "id": "c5aed35a-d9ff-437d-82d6-68f0cda8ea94",
  27. "%s": "i_do_not_exist_on_prop_level",
  28. "name": "prop",
  29. "value": [
  30. 1,
  31. 2,
  32. 3
  33. ],
  34. "type": "int"
  35. }
  36. ]
  37. }
  38. ]
  39. },
  40. "odml-version": "1.1"
  41. }
  42. """.strip()
  43. _SEC_CREATION_ERROR_DOC = """
  44. {
  45. "Document": {
  46. "id": "6af2a3ec-9f3a-42d6-a59d-95f3ccbaa383",
  47. "sections": [
  48. {
  49. "id": "1113c79c-a7d7-471e-be16-e085caa851fb",
  50. "name": "sec",
  51. "type": "test",
  52. "sections": [
  53. {
  54. "id": "1213c79c-a7d7-471e-be16-e085caa851fb",
  55. "name": "%s",
  56. "type": "test"
  57. },
  58. {
  59. "id": [
  60. "I-am-so-kaputt"
  61. ],
  62. "name": "%s",
  63. "type": "test"
  64. }
  65. ]
  66. }
  67. ]
  68. },
  69. "odml-version": "1.1"
  70. }
  71. """.strip()
  72. _PROP_CREATION_ERROR_DOC = """
  73. {
  74. "Document": {
  75. "id": "6af2a3ec-9f3a-42d6-a59d-95f3ccbaa383",
  76. "sections": [
  77. {
  78. "id": "51f3c79c-a7d7-471e-be16-e085caa851fb",
  79. "type": "test",
  80. "name": "sec",
  81. "properties": [
  82. {
  83. "id": "121ed35a-d9ff-437d-82d6-68f0cda8ea94",
  84. "name": "valid_prop"
  85. },
  86. {
  87. "id": "122ed35a-d9ff-437d-82d6-68f0cda8ea94",
  88. "name": "invalid_prop",
  89. "value": [
  90. "a",
  91. "b"
  92. ],
  93. "type": "int"
  94. }
  95. ]
  96. }
  97. ]
  98. },
  99. "odml-version": "1.1"
  100. }
  101. """.strip()
  102. class TestJSONParser(unittest.TestCase):
  103. def setUp(self):
  104. self.base_path = RES_DIR
  105. self.json_reader = dict_parser.DictReader(show_warnings=False)
  106. self.tmp_dir_path = create_test_dir(__file__)
  107. def tearDown(self):
  108. if self.tmp_dir_path and os.path.exists(self.tmp_dir_path):
  109. shutil.rmtree(self.tmp_dir_path)
  110. def _prepare_doc(self, file_name, file_content):
  111. file_path = os.path.join(self.tmp_dir_path, file_name)
  112. with open(file_path, "w") as dump_file:
  113. dump_file.write(file_content)
  114. with open(file_path) as raw_data:
  115. parsed_doc = json.load(raw_data)
  116. return parsed_doc
  117. def test_missing_root(self):
  118. filename = "missing_root.json"
  119. message = "Missing root element"
  120. with open(os.path.join(self.base_path, filename)) as json_data:
  121. parsed_doc = json.load(json_data)
  122. with self.assertRaises(ParserException) as exc:
  123. _ = self.json_reader.to_odml(parsed_doc)
  124. self.assertIn(message, str(exc.exception))
  125. def test_missing_version(self):
  126. filename = "missing_version.json"
  127. message = "Could not find odml-version"
  128. with open(os.path.join(self.base_path, filename)) as json_data:
  129. parsed_doc = json.load(json_data)
  130. with self.assertRaises(ParserException) as exc:
  131. _ = self.json_reader.to_odml(parsed_doc)
  132. self.assertIn(message, str(exc.exception))
  133. def test_invalid_version(self):
  134. filename = "invalid_version.json"
  135. with open(os.path.join(self.base_path, filename)) as json_data:
  136. parsed_doc = json.load(json_data)
  137. with self.assertRaises(InvalidVersionException):
  138. _ = self.json_reader.to_odml(parsed_doc)
  139. def test_invalid_attribute_handling(self):
  140. filename = "invalid_attributes.yaml"
  141. inv_doc_attr = "invalid_doc_attr"
  142. inv_sec_attr = "invalid_sec_attr"
  143. inv_prop_attr = "invalid_prop_attr"
  144. file_content = _INVALID_ATTRIBUTE_HANDLING_DOC % (inv_doc_attr, inv_sec_attr, inv_prop_attr)
  145. parsed_doc = self._prepare_doc(filename, file_content)
  146. # Test ParserException on default parse
  147. exc_msg = "Invalid element"
  148. with self.assertRaises(ParserException) as exc:
  149. _ = self.json_reader.to_odml(parsed_doc)
  150. self.assertIn(exc_msg, str(exc.exception))
  151. # Test success on ignore_error parse
  152. self.json_reader.ignore_errors = True
  153. doc = self.json_reader.to_odml(parsed_doc)
  154. self.assertEqual(len(doc.sections), 1)
  155. self.assertEqual(len(doc.sections["sec"].properties), 1)
  156. self.assertEqual(len(self.json_reader.warnings), 3)
  157. for msg in self.json_reader.warnings:
  158. self.assertIn("Error", msg)
  159. self.assertTrue(inv_doc_attr in msg or inv_sec_attr in msg or inv_prop_attr in msg)
  160. def test_sec_creation_error(self):
  161. filename = "broken_section.yaml"
  162. valid = "valid_sec"
  163. invalid = "invalid_sec"
  164. file_content = _SEC_CREATION_ERROR_DOC % (valid, invalid)
  165. parsed_doc = self._prepare_doc(filename, file_content)
  166. # Test ParserException on default parse
  167. exc_msg = "Section not created"
  168. with self.assertRaises(ParserException) as exc:
  169. _ = self.json_reader.to_odml(parsed_doc)
  170. self.assertIn(exc_msg, str(exc.exception))
  171. # Test success on ignore_error parse
  172. self.json_reader.ignore_errors = True
  173. doc = self.json_reader.to_odml(parsed_doc)
  174. self.assertEqual(len(doc.sections["sec"].sections), 1)
  175. self.assertIn(valid, doc.sections["sec"].sections)
  176. self.assertNotIn(invalid, doc.sections["sec"].sections)
  177. self.assertEqual(len(self.json_reader.warnings), 1)
  178. for msg in self.json_reader.warnings:
  179. self.assertIn("Error", msg)
  180. self.assertIn(exc_msg, msg)
  181. def test_prop_creation_error(self):
  182. filename = "broken_property.yaml"
  183. parsed_doc = self._prepare_doc(filename, _PROP_CREATION_ERROR_DOC)
  184. # Test ParserException on default parse
  185. exc_msg = "Property not created"
  186. with self.assertRaises(ParserException) as exc:
  187. _ = self.json_reader.to_odml(parsed_doc)
  188. self.assertIn(exc_msg, str(exc.exception))
  189. # Test success on ignore_error parse
  190. self.json_reader.ignore_errors = True
  191. doc = self.json_reader.to_odml(parsed_doc)
  192. self.assertEqual(len(doc.sections["sec"].properties), 1)
  193. self.assertIn("valid_prop", doc.sections["sec"].properties)
  194. self.assertNotIn("invalid_prop", doc.sections["sec"].properties)
  195. self.assertEqual(len(self.json_reader.warnings), 1)
  196. for msg in self.json_reader.warnings:
  197. self.assertIn("Error", msg)
  198. self.assertIn(exc_msg, msg)