1
0

test_samplefile.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. import odml
  2. import unittest
  3. import os
  4. import sys
  5. import re
  6. import tempfile
  7. from odml.info import FORMAT_VERSION
  8. from odml.tools import xmlparser
  9. from odml.tools import dumper
  10. try:
  11. unicode = unicode
  12. except NameError:
  13. unicode = str
  14. def dump(doc, filename):
  15. """
  16. Helper function to dump a document for debugging purposes
  17. """
  18. if sys.version_info < (3, 0):
  19. odml_string = unicode(xmlparser.XMLWriter(doc))
  20. else:
  21. odml_string = str(xmlparser.XMLWriter(doc))
  22. open(filename, "w").write(odml_string)
  23. def parse(data):
  24. """
  25. Parses strings to quickly create odml-documents
  26. e.g.:
  27. s1[t1] mapping [T1]
  28. - p1
  29. s2[t1]
  30. - s21[t2] linked to /s1/s2
  31. """
  32. lines = data.strip(" ").strip("\n").split("\n")
  33. offset = len(re.compile('(\s*)').match(lines[0]).group())
  34. pat = re.compile(r'(?P<name>\w+)(\[(?P<type>\w+)\])?(\s+mapping \[(?P<dst>'
  35. '[\w:]+)\])?(\s+linked to (?P<link>[\w/]+))?')
  36. parents = [odml.Document(), None]
  37. for line in lines:
  38. line = line[offset:]
  39. while len(parents) > 1:
  40. parpref = (len(parents) - 2) * 2
  41. if line.startswith(" " * parpref):
  42. line = line[parpref:]
  43. break
  44. parents.pop()
  45. if line.startswith('- '):
  46. line = line[2:]
  47. else:
  48. parents.pop()
  49. try:
  50. m = pat.match(line).groupdict()
  51. except:
  52. print("error parsing", repr(line))
  53. raise
  54. if m['type'] is None:
  55. obj = odml.Property(name=m['name'], value="[val]")
  56. else:
  57. obj = odml.Section(name=m['name'], type=m['type'])
  58. if m['dst'] is not None:
  59. obj.mapping = 'map#%s' % m['dst']
  60. if m['link'] is not None:
  61. obj._link = m['link']
  62. parents[-1].append(obj)
  63. parents.append(obj)
  64. return parents[0]
  65. class SampleFileCreator:
  66. def create_document(self):
  67. doc = odml.Document()
  68. for i in range(3):
  69. doc.append(self.create_section("sec %d" % i))
  70. return doc
  71. def create_section(self, name, depth=0):
  72. s = odml.Section(name=name, type=name.replace("sec", "type"))
  73. if depth < 1:
  74. for i in range(2):
  75. s.append(self.create_section("%s,%d" %
  76. (name, i), depth=depth + 1))
  77. if name.endswith("1"):
  78. for i in range(3):
  79. s.append(self.create_property("%s:%d" % (name, i)))
  80. return s
  81. def create_property(self, name):
  82. return odml.Property(name=name.replace("sec", "prop"),
  83. value=name.replace("sec", "val"))
  84. class SampleFileCreatorTest(unittest.TestCase):
  85. def test_samplefile(self):
  86. doc = SampleFileCreator().create_document()
  87. # dumper.dumpDoc(doc)
  88. class SampleFileOperationTest(unittest.TestCase):
  89. def setUp(self):
  90. doc = SampleFileCreator().create_document()
  91. doc.sections['sec 0'].sections['sec 0,1'].type = "test"
  92. self.doc = doc
  93. def test_find_key(self):
  94. self.assertEqual(self.doc.find(key="sec 1,1"), None)
  95. # find distant child
  96. sec = self.doc.find_related(key="sec 1,1")
  97. self.assertEqual(sec.name, "sec 1,1")
  98. # find sibling
  99. res = sec.find_related(key="sec 0,0")
  100. self.assertEqual(res, None)
  101. sec = sec.find_related(key="sec 1,0")
  102. self.assertEqual(sec.name, "sec 1,0")
  103. # find parent
  104. res = sec.find_related(key="sec 0")
  105. self.assertEqual(res, None)
  106. sec = sec.find_related(key="sec 1")
  107. self.assertEqual(sec.name, "sec 1")
  108. # find section by type
  109. self.assertEqual(self.doc.find_related(type="test").name, "sec 0,1")
  110. def test_xml_writer_version(self):
  111. doc = odml.Document()
  112. if sys.version_info < (3, 0):
  113. val = unicode(xmlparser.XMLWriter(doc))
  114. else:
  115. val = str(xmlparser.XMLWriter(doc))
  116. self.assertIn('version="%s"' % FORMAT_VERSION, val)
  117. doc = xmlparser.XMLReader().from_string(val)
  118. # This test is switched off until the XML versioning support is implemented
  119. # self.assertEqual(doc._xml_version, FORMAT_VERSION)
  120. def test_save(self):
  121. for module in [xmlparser.XMLWriter]:
  122. doc = module(self.doc)
  123. import tempfile
  124. path = tempfile.gettempdir()
  125. path = os.path.join(path, "temp.odml")
  126. doc.write_file(path)
  127. os.unlink(path)
  128. def test_restore(self):
  129. try:
  130. from StringIO import StringIO
  131. except ImportError:
  132. from io import StringIO
  133. modules = [(xmlparser.XMLWriter, xmlparser.XMLReader)]
  134. for Writer, Reader in modules:
  135. doc = Writer(self.doc)
  136. if sys.version_info < (3, 0):
  137. doc = StringIO(unicode(doc))
  138. else:
  139. doc = StringIO(str(doc))
  140. doc = Reader().from_file(doc)
  141. self.assertEqual(doc, self.doc)
  142. # for a,b in zip(doc.sections, self.doc.sections):
  143. # print "sec cmp", a, b
  144. # self.assertEqual(a, b)
  145. # print "A ---------------------------------"
  146. # for sec in doc.sections:
  147. # xmlparser.dumpSection(sec)
  148. # print "B ---------------------------------"
  149. # for sec in self.doc.sections:
  150. # xmlparser.dumpSection(sec)
  151. # print "-----------------------------------"
  152. class AttributeTest(unittest.TestCase):
  153. def test_value_int(self):
  154. p = odml.Property("test", 1, dtype="int")
  155. self.assertEqual(p.values[0], 1)
  156. def test_conversion_int_to_float(self):
  157. p = odml.Property("test", "1", dtype="int")
  158. self.assertEqual(p.dtype, "int")
  159. self.assertIsInstance(p.values[0], int)
  160. p.dtype = "float" # change dtype
  161. self.assertEqual(p.dtype, "float")
  162. self.assertEqual(p.values[0], 1.0)
  163. def test_conversion_float_to_int(self):
  164. p = odml.Property("test", "1.5", dtype="float")
  165. self.assertEqual(p.dtype, "float")
  166. p.dtype = "int"
  167. self.assertEqual(p.dtype, "int")
  168. self.assertEqual(p.values[0], 1)
  169. def test_value_float(self):
  170. p = odml.Property("test", value="1.5", dtype="float")
  171. self.assertEqual(p.values[0], 1.5)
  172. class CopyTest(unittest.TestCase):
  173. def setUp(self):
  174. self.p = odml.Property(name="test", value=1)
  175. def test_dependence(self):
  176. a = self.p
  177. b = self.p
  178. self.assertEqual(a, b)
  179. a.values = 5
  180. self.assertEqual(a, b)
  181. self.assertEqual(a.values, b.values)
  182. def test_independence(self):
  183. a = self.p.clone()
  184. b = self.p.clone()
  185. self.assertEqual(a, b)
  186. a.values = 5
  187. self.assertNotEqual(a, b)
  188. # self.assertUn
  189. class MiscTest(unittest.TestCase):
  190. def setUp(self):
  191. self.doc = SampleFileCreator().create_document()
  192. def test_paths(self):
  193. sec = odml.Section("bar")
  194. self.assertEqual(sec._get_relative_path("/a", "/b"), "/b")
  195. self.assertEqual(sec._get_relative_path("/a", "/a/b"), "b")
  196. self.assertEqual(sec._get_relative_path("/a/b", "/a/c"), "../c")
  197. self.assertEqual(sec._get_relative_path("/a/b/c", "/a"), "../..")
  198. self.assertEqual(sec._get_relative_path("/a/b", "/a"), "..")
  199. def test_section_path(self):
  200. sec1 = self.doc.sections[1]
  201. sec10 = sec1.sections[0]
  202. sec11 = sec1.sections[1]
  203. path = sec10.get_path()
  204. self.assertEqual(path, "/%s/%s" % (sec1.name, sec10.name))
  205. self.assertEqual(self.doc.get_path(), "/")
  206. self.assertEqual(sec10.get_relative_path(sec1), "..")
  207. path_to_sec10 = sec1.get_relative_path(sec10)
  208. self.assertEqual(path_to_sec10, sec10.name)
  209. self.assertIs(sec1.get_section_by_path(path_to_sec10), sec10)
  210. path_to_sec11 = sec10.get_relative_path(sec11)
  211. self.assertEqual(path_to_sec11, "../" + sec11.name)
  212. self.assertIs(sec10.get_section_by_path(path_to_sec11), sec11)
  213. def test_findall_related(self):
  214. doc = parse("""
  215. s1[T1]
  216. - s2[T1]
  217. """)
  218. self.assertEqual(len(doc.find_related(type="T1", findAll=True)), 2)
  219. doc = parse("""
  220. s0[T1]
  221. - s00[T2]
  222. s1[T2]
  223. s2[T1]
  224. """)
  225. self.assertEqual(
  226. len(doc.sections[1].find_related(type="T1", findAll=True)), 2)
  227. def test_reorder_post(self):
  228. old_index = self.doc.sections[0].reorder(2)
  229. self.assertEqual(old_index, 0)
  230. self.assertEqual(self.doc.sections[0].name, "sec 1")
  231. self.assertEqual(self.doc.sections[1].name, "sec 2")
  232. self.assertEqual(self.doc.sections[2].name, "sec 0")
  233. def test_reorder_first(self):
  234. old_index = self.doc.sections[2].reorder(0)
  235. self.assertEqual(old_index, 2)
  236. self.assertEqual(self.doc.sections[0].name, "sec 2")
  237. self.assertEqual(self.doc.sections[1].name, "sec 0")
  238. self.assertEqual(self.doc.sections[2].name, "sec 1")
  239. def test_get_section_by_path(self):
  240. sec0 = self.doc.sections[0]
  241. sec1 = self.doc.sections[1]
  242. sec01 = sec0.sections[1]
  243. sec10 = sec1.sections[0]
  244. sec11 = sec1.sections[1]
  245. # test absolute path
  246. current = self.doc.get_section_by_path(sec10.get_path())
  247. self.assertEqual(current, sec10)
  248. # test relative path with ../
  249. current = sec10.get_section_by_path(sec10.get_relative_path(sec11))
  250. self.assertEqual(current, sec11)
  251. # test relative path with ./
  252. current = sec1.get_section_by_path(
  253. "./" + sec1.get_relative_path(sec11))
  254. self.assertEqual(current, sec11)
  255. # test relative path
  256. current = sec1.get_section_by_path(sec1.get_relative_path(sec11))
  257. self.assertEqual(current, sec11)
  258. # test wrong parent
  259. wrongpath = "../" + sec10.get_relative_path(sec11)
  260. self.assertRaises(ValueError, sec10.get_section_by_path, wrongpath)
  261. # test wrong child
  262. wrongpath = sec1.get_relative_path(sec10) + "/foo"
  263. self.assertRaises(ValueError, sec1.get_section_by_path, wrongpath)
  264. # test absolute path with no document
  265. newsec = SampleFileCreator().create_section("foo", 0)
  266. path = newsec.sections[0].get_path()
  267. self.assertRaises(ValueError,
  268. newsec.sections[1].get_section_by_path, path)
  269. # test path with property is invalid
  270. path = sec11.properties[0].get_path()
  271. self.assertRaises(ValueError, self.doc.get_section_by_path, path)
  272. def test_get_property_by_path(self):
  273. sec0 = self.doc.sections[0]
  274. sec1 = self.doc.sections[1]
  275. sec00 = self.doc.sections[0].sections[0]
  276. sec11 = self.doc.sections[1].sections[1]
  277. sec10 = self.doc.sections[1].sections[0]
  278. prop = sec11.properties[0]
  279. # test absolute path from document
  280. current = self.doc.get_property_by_path(prop.get_path())
  281. self.assertEqual(current, prop)
  282. # test absolute path from section
  283. current = sec00.get_property_by_path(prop.get_path())
  284. self.assertEqual(current, prop)
  285. # test relative path from section
  286. manualpath = "../%s/%s:%s" % (sec1.name, sec11.name, prop.name)
  287. current = sec0.get_property_by_path(manualpath)
  288. self.assertEqual(current, prop)
  289. # test non-existing property
  290. wrongpath = sec10.get_relative_path(sec11) + ":foo"
  291. self.assertRaises(ValueError, sec1.get_property_by_path, wrongpath)
  292. # test path with section is invalid
  293. wrongpath = sec11.get_path()
  294. self.assertRaises(ValueError, sec1.get_property_by_path, wrongpath)
  295. def test_save_version(self):
  296. tmp_file = os.path.join(tempfile.gettempdir(), "example.odml")
  297. self.doc.version = '2.4'
  298. writer = xmlparser.XMLWriter(self.doc)
  299. writer.write_file(tmp_file)
  300. restored = xmlparser.load(tmp_file)
  301. self.assertEqual(self.doc.version, restored.version)