test_version_converter.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. import io
  2. import os
  3. import shutil
  4. import tempfile
  5. import unittest
  6. try:
  7. import urllib.request as urllib2
  8. from urllib.request import pathname2url
  9. except ImportError:
  10. import urllib2
  11. from urllib import pathname2url
  12. from contextlib import contextmanager
  13. from lxml import etree as ET
  14. from odml.terminology import REPOSITORY_BASE
  15. from odml.tools.version_converter import VersionConverter
  16. try:
  17. unicode = unicode
  18. except NameError:
  19. unicode = str
  20. class TestVersionConverter(unittest.TestCase):
  21. def setUp(self):
  22. dir_path = os.path.dirname(os.path.realpath(__file__))
  23. self.basepath = os.path.join(dir_path, "resources")
  24. self.VC = VersionConverter
  25. self.doc = """
  26. <odML version="1">
  27. <date>2008-07-07</date>
  28. <section>
  29. <property>
  30. <value>0<unit>deg</unit><type>int</type><uncertainty/></value>
  31. <value>45<unit>deg</unit><type>int</type></value>
  32. <name>Orientations</name>
  33. </property>
  34. <type>some sec type</type>
  35. <name>sec_name</name>
  36. </section>
  37. <section>
  38. <type>some sec type</type>
  39. <name>sec_name</name>
  40. <property>
  41. <name>prop_name</name>
  42. </property>
  43. <property>
  44. <name>prop_name</name>
  45. </property>
  46. </section>
  47. <author>Author</author>
  48. </odML>
  49. """
  50. self.tmp_dir = None
  51. def tearDown(self):
  52. if self.tmp_dir and os.path.exists(self.tmp_dir):
  53. shutil.rmtree(self.tmp_dir)
  54. @contextmanager
  55. def assertNotRaises(self, exc_type):
  56. try:
  57. yield None
  58. except exc_type:
  59. raise self.failureException('{} raised'.format(exc_type.__name__))
  60. def test_replace_same_name_entites(self):
  61. root = ET.fromstring(self.doc)
  62. sec_names = []
  63. sec_elems = []
  64. for sec in root.iter("section"):
  65. sec_names.append(sec.find("name").text)
  66. sec_elems.append(sec)
  67. self.assertEqual(sec_names[0], "sec_name")
  68. self.assertEqual(sec_names[0], sec_names[1])
  69. props_names = []
  70. for prop in sec_elems[1].iter("property"):
  71. props_names.append(prop.find("name").text)
  72. self.assertEqual(props_names[0], "prop_name")
  73. self.assertEqual(props_names[0], props_names[1])
  74. tree = ET.ElementTree(root)
  75. tree = self.VC._replace_same_name_entities(tree)
  76. root = tree.getroot()
  77. sec_names = []
  78. sec_elems = []
  79. for sec in root.iter("section"):
  80. sec_names.append(sec.find("name").text)
  81. sec_elems.append(sec)
  82. self.assertEqual(sec_names[0], "sec_name")
  83. self.assertEqual(sec_names[1], "sec_name-2")
  84. props_names = []
  85. for prop in sec_elems[1].iter("property"):
  86. props_names.append(prop.find("name").text)
  87. self.assertEqual(props_names[0], "prop_name")
  88. self.assertEqual(props_names[1], "prop_name-2")
  89. def test_convert_odml_file(self):
  90. with self.assertRaises(Exception) as exc:
  91. self.VC("/not_valid_path").convert()
  92. self.assertIn("Cannot parse provided file", str(exc.exception))
  93. root = ET.fromstring(self.doc)
  94. prop = root.find("section").find("property")
  95. val_elems = []
  96. for val in prop.iter("value"):
  97. val_elems.append(val)
  98. self.assertEqual(val_elems[0].find("unit").text, "deg")
  99. self.assertEqual(val_elems[0].find("type").text, "int")
  100. self.assertEqual(val_elems[0].find("uncertainty").text, None)
  101. self.assertEqual(prop.find("unit"), None)
  102. self.assertEqual(prop.find("type"), None)
  103. file = io.StringIO(unicode(self.doc))
  104. vc = self.VC(file)
  105. tree = vc._convert(vc._parse_xml())
  106. root = tree.getroot()
  107. prop = root.find("section").find("property")
  108. val_elems = []
  109. for val in prop.iter("value"):
  110. val_elems.append(val)
  111. self.assertEqual(len(val_elems), 1)
  112. self.assertEqual(val_elems[0].find("unit"), None)
  113. self.assertEqual(val_elems[0].find("type"), None)
  114. self.assertEqual(val_elems[0].find("uncertainty"), None)
  115. self.assertEqual(val_elems[0].text, "[0,45]")
  116. self.assertEqual(prop.find("unit").text, "deg")
  117. self.assertEqual(len(prop.findall("unit")), 1)
  118. self.assertEqual(prop.find("type").text, "int")
  119. self.assertEqual(len(prop.findall("type")), 1)
  120. self.assertEqual(prop.find("uncertainty").text, None)
  121. def test_convert_odml_file_document(self):
  122. """Test proper conversion of the odml.Document entity from
  123. odml model version 1 to version 1.1.
  124. The test checks for the proper conversion of all valid
  125. Document tags and exclusion of non-Document tags.
  126. """
  127. dir_path = os.path.dirname(os.path.realpath(__file__))
  128. repo_file = os.path.join(dir_path, "resources",
  129. "local_repository_file_v1.1.xml")
  130. local_url = "file://%s" % repo_file
  131. repo_old_file = os.path.join(dir_path, "resources",
  132. "local_repository_file_v1.0.xml")
  133. local_old_url = "file://%s" % repo_old_file
  134. doc = """
  135. <odML version="1">
  136. <!-- Valid Document tags test -->
  137. <author>Document author</author>
  138. <version>1</version>
  139. <date>2017-10-18</date>
  140. <repository>%s</repository>
  141. <section><name>Document section</name></section>
  142. <!-- Unsupported Document tags test -->
  143. <invalid>Invalid Document tag</invalid>
  144. <property>Invalid Document property</property>
  145. <value>Invalid Document value</value>
  146. </odML>
  147. """ % local_url
  148. invalid_repo_doc = """
  149. <odML version="1">
  150. <repository>Unresolvable</repository>
  151. <section><name>Document section</name></section>
  152. </odML>
  153. """
  154. old_repo_doc = """
  155. <odML version="1">
  156. <repository>%s</repository>
  157. <section><name>Document section</name></section>
  158. </odML>
  159. """ % local_old_url
  160. file = io.StringIO(unicode(doc))
  161. vc = self.VC(file)
  162. conv_doc = vc._convert(vc._parse_xml())
  163. root = conv_doc.getroot()
  164. # Test export of Document tags, repository is excluded
  165. self.assertEqual(len(root.findall("author")), 1)
  166. self.assertEqual(len(root.findall("date")), 1)
  167. self.assertEqual(len(root.findall("repository")), 1)
  168. self.assertEqual(len(root.findall("section")), 1)
  169. # Test absence of non-Document tags
  170. self.assertEqual(len(root.findall("invalid")), 0)
  171. self.assertEqual(len(root.findall("property")), 0)
  172. self.assertEqual(len(root.findall("value")), 0)
  173. # Test warning message on non-importable repository
  174. file = io.StringIO(unicode(invalid_repo_doc))
  175. vc = self.VC(file)
  176. conv_doc = vc._convert(vc._parse_xml())
  177. root = conv_doc.getroot()
  178. self.assertEqual(root.findall("repository")[0].text, "Unresolvable")
  179. self.assertIn("not odML v1.1 compatible", vc.conversion_log[0])
  180. # Test warning message on old repository
  181. file = io.StringIO(unicode(old_repo_doc))
  182. vc = self.VC(file)
  183. conv_doc = vc._convert(vc._parse_xml())
  184. root = conv_doc.getroot()
  185. self.assertEqual(root.findall("repository")[0].text, local_old_url)
  186. self.assertIn("not odML v1.1 compatible", vc.conversion_log[0])
  187. def test_convert_odml_file_section(self):
  188. """Test proper conversion of the odml.Section entity from
  189. odml model version 1 to version 1.1.
  190. The test checks for the proper conversion of all valid
  191. Section tags and exclusion of non-Section tags.
  192. """
  193. dir_path = os.path.dirname(os.path.realpath(__file__))
  194. repo_file = os.path.join(dir_path, "resources",
  195. "local_repository_file_v1.1.xml")
  196. local_url = "file://%s" % repo_file
  197. repo_old_file = os.path.join(dir_path, "resources",
  198. "local_repository_file_v1.0.xml")
  199. local_old_url = "file://%s" % repo_old_file
  200. doc = """
  201. <odML version="1">
  202. <!-- Valid Section tags test -->
  203. <section>
  204. <name>Section name</name>
  205. <type>Section type</type>
  206. <definition>Section definition</definition>
  207. <reference>Section reference</reference>
  208. <link>Section link</link>
  209. <repository>%s</repository>
  210. <include>Section include</include>
  211. <property><name>Section Property 1</name></property>
  212. <property><name>Section Property 2</name></property>
  213. <section>
  214. <name>SubSection name</name>
  215. <type>SubSection type</type>
  216. <definition>SubSection definition</definition>
  217. <reference>SubSection reference</reference>
  218. <link>SubSection link</link>
  219. <repository>%s</repository>
  220. <include>SubSection include</include>
  221. <property><name>SubSection Property</name></property>
  222. </section>
  223. </section>
  224. <section>
  225. <name>Unsupported Section tags test</name>
  226. <invalid>Invalid tag</invalid>
  227. <value>Invalid Value tag</value>
  228. <mapping>Unsupported mapping tag</mapping>
  229. </section>
  230. </odML>
  231. """ % (local_url, local_url)
  232. file = io.StringIO(unicode(doc))
  233. vc = self.VC(file)
  234. conv_doc = vc._convert(vc._parse_xml())
  235. root = conv_doc.getroot()
  236. sec = root.findall("section")
  237. self.assertEqual(len(sec), 2)
  238. # Test valid section tags.
  239. self.assertEqual(len(sec[0]), 10)
  240. self.assertEqual(sec[0].find("name").text, "Section name")
  241. self.assertEqual(sec[0].find("type").text, "Section type")
  242. self.assertEqual(sec[0].find("definition").text, "Section definition")
  243. self.assertEqual(sec[0].find("reference").text, "Section reference")
  244. self.assertEqual(sec[0].find("link").text, "Section link")
  245. self.assertEqual(sec[0].find("repository").text, local_url)
  246. self.assertEqual(sec[0].find("include").text, "Section include")
  247. self.assertEqual(len(sec[0].findall("property")), 2)
  248. self.assertEqual(len(sec[0].findall("section")), 1)
  249. # Test valid subsection tags.
  250. subsec = sec[0].find("section")
  251. self.assertEqual(len(subsec), 8)
  252. self.assertEqual(subsec.find("name").text, "SubSection name")
  253. self.assertEqual(subsec.find("type").text, "SubSection type")
  254. self.assertEqual(subsec.find("definition").text, "SubSection definition")
  255. self.assertEqual(subsec.find("reference").text, "SubSection reference")
  256. self.assertEqual(subsec.find("link").text, "SubSection link")
  257. self.assertEqual(subsec.find("repository").text, local_url)
  258. self.assertEqual(subsec.find("include").text, "SubSection include")
  259. self.assertEqual(len(subsec.findall("property")), 1)
  260. # Test absence of non-Section tags
  261. self.assertEqual(len(sec[1]), 1)
  262. self.assertEqual(len(sec[1].findall("name")), 1)
  263. # Test presence of v1.0 repository tag and warning log entry
  264. doc = """
  265. <odML version="1">
  266. <section>
  267. <name>Unsupported Section include test</name>
  268. <repository>%s</repository>
  269. </section>
  270. </odML>""" % local_old_url
  271. file = io.StringIO(unicode(doc))
  272. vc = self.VC(file)
  273. conv_doc = vc._convert(vc._parse_xml())
  274. sec = conv_doc.getroot().findall("section")
  275. self.assertEqual(sec[0].find("repository").text, local_old_url)
  276. self.assertIn("not odML v1.1 compatible", vc.conversion_log[0])
  277. # Test presence of v1.0 include tag and warning log entry
  278. doc = """
  279. <odML version="1">
  280. <section>
  281. <name>Unsupported Section include test</name>
  282. <include>%s</include>
  283. </section>
  284. </odML>""" % local_old_url
  285. file = io.StringIO(unicode(doc))
  286. vc = self.VC(file)
  287. conv_doc = vc._convert(vc._parse_xml())
  288. sec = conv_doc.getroot().findall("section")
  289. self.assertEqual(sec[0].find("include").text, local_old_url)
  290. self.assertIn("not odML v1.1 compatible", vc.conversion_log[0])
  291. def test_convert_odml_file_property(self):
  292. """Test proper conversion of the odml.Property entity from
  293. odml model version 1 to version 1.1.
  294. The test checks for the proper conversion of all valid
  295. Property tags and exclusion of non-Property tags.
  296. """
  297. doc = """
  298. <odML version="1">
  299. <section>
  300. <name>Valid Property tags test</name>
  301. <property>
  302. <name>Property name</name>
  303. <type>Property type</type>
  304. <definition>Property definition</definition>
  305. <dependency>Property dependency</dependency>
  306. <dependency_value>Property dependency value</dependency_value>
  307. </property>
  308. </section>
  309. <section>
  310. <name>Unsupported Property tags test</name>
  311. <property>
  312. <name>Invalid Property</name>
  313. <invalid>Invalid tag</invalid>
  314. <section><name>Invalid Section</name></section>
  315. </property>
  316. <property>Property with no name</property>
  317. </section>
  318. </odML>
  319. """
  320. file = io.StringIO(unicode(doc))
  321. vc = self.VC(file)
  322. conv_doc = vc._convert(vc._parse_xml())
  323. root = conv_doc.getroot()
  324. sec = root.findall("section")
  325. # Test valid Property tags
  326. self.assertEqual(sec[0].find("name").text, "Valid Property tags test")
  327. self.assertEqual(len(sec[0].findall("property")), 1)
  328. prop = sec[0].find("property")
  329. self.assertEqual(len(prop), 5)
  330. self.assertEqual(prop.find("name").text, "Property name")
  331. self.assertEqual(prop.find("type").text, "Property type")
  332. self.assertEqual(prop.find("definition").text, "Property definition")
  333. self.assertEqual(prop.find("dependency").text, "Property dependency")
  334. self.assertEqual(prop.find("dependencyvalue").text, "Property dependency value")
  335. # Test non-import of Property w/o name
  336. self.assertEqual(len(sec[1].findall("property")), 1)
  337. # Test absence of non-Property tags
  338. prop = sec[1].find("property")
  339. self.assertEqual(len(prop), 1)
  340. self.assertEqual(len(prop.findall("name")), 1)
  341. def test_convert_odml_file_value(self):
  342. """Test proper conversion of the odml.Value entity from
  343. odml model version 1 to version 1.1.
  344. The test checks for the proper conversion of all valid
  345. Value tags and exclusion of non-Value tags.
  346. """
  347. doc = """
  348. <odML version="1">
  349. <section>
  350. <name>Values export test</name>
  351. <property>
  352. <name>Single value export</name>
  353. <value>1</value>
  354. </property>
  355. <property>
  356. <name>Multiple values export</name>
  357. <value>1</value>
  358. <value>2</value>
  359. <value>3</value>
  360. </property>
  361. <property>
  362. <name>Empty value export</name>
  363. <value></value>
  364. <value></value>
  365. <value></value>
  366. <value></value>
  367. </property>
  368. <property>
  369. <name>Supported Value tags export</name>
  370. <value>0.1
  371. <type>float</type>
  372. <uncertainty>0.05</uncertainty>
  373. <unit>mV</unit>
  374. <filename>raw.txt</filename>
  375. <reference>Value reference</reference>
  376. </value>
  377. </property>
  378. <property>
  379. <name>Supported Multiple Value tags export</name>
  380. <value>0.1
  381. <unit>mV</unit>
  382. <filename>raw.txt</filename>
  383. <reference>Value reference</reference>
  384. </value>
  385. <value>0.2
  386. <type>float</type>
  387. <uncertainty>0.05</uncertainty>
  388. <unit>mV</unit>
  389. <filename>raw.txt</filename>
  390. <reference>Value reference</reference>
  391. </value>
  392. <value>3
  393. <type>int</type>
  394. <uncertainty>0.06</uncertainty>
  395. <unit>kV</unit>
  396. <filename>raw2.txt</filename>
  397. <reference>Value reference 2</reference>
  398. </value>
  399. </property>
  400. <property>
  401. <name>Unsupported Value tags export</name>
  402. <value>
  403. <invalid>Invalid Value tag</invalid>
  404. <encoder>Encoder</encoder>
  405. <checksum>Checksum</checksum>
  406. </value>
  407. </property>
  408. <property>
  409. <name>Unsupported binary value type replace</name>
  410. <value>0
  411. <type>binary</type>
  412. </value>
  413. </property>
  414. <property>
  415. <name>Unsupported binary value dtype replace</name>
  416. <value>1
  417. <dtype>binary</dtype>
  418. </value>
  419. </property>
  420. <property>
  421. <value>Single, string, value, with, many, commata.<type>string</type></value>
  422. <name>testSingleString</name>
  423. </property>
  424. <property>
  425. <value>A<type>string</type></value>
  426. <value>B<type>string</type></value>
  427. <value>C<type>string</type></value>
  428. <name>testStringList</name>
  429. </property>
  430. <property>
  431. <value> Single string value with wrapping whitespace <type>string</type></value>
  432. <name>testStringWhiteSpace</name>
  433. </property>
  434. <property>
  435. <value> Multiple Strings <type>string</type></value>
  436. <value> with wrapping <type>string</type></value>
  437. <value> Whitespace <type>string</type></value>
  438. <name>testStringListWhiteSpace</name>
  439. </property>
  440. <property>
  441. <value> 1 <type>int</type></value>
  442. <value> 2 <type>int</type></value>
  443. <value> 3 <type>int</type></value>
  444. <name>testIntListWhiteSpace</name>
  445. </property>
  446. </section>
  447. </odML>
  448. """
  449. file = io.StringIO(unicode(doc))
  450. vc = self.VC(file)
  451. conv_doc = vc._convert(vc._parse_xml())
  452. root = conv_doc.getroot()
  453. sec = root.find("section")
  454. self.assertEqual(len(sec), 14)
  455. # Test single value export
  456. prop = sec.findall("property")[0]
  457. self.assertEqual(len(prop), 2)
  458. self.assertEqual(prop.find("value").text, "1")
  459. # Test multiple value export
  460. prop = sec.findall("property")[1]
  461. self.assertEqual(len(prop), 2)
  462. self.assertEqual(prop.find("value").text, "[1,2,3]")
  463. # Test empty value export
  464. prop = sec.findall("property")[2]
  465. self.assertEqual(len(prop), 1)
  466. self.assertEqual(prop.find("name").text, "Empty value export")
  467. # Test valid Value tags
  468. prop = sec.findall("property")[3]
  469. self.assertEqual(len(prop), 7)
  470. self.assertEqual(prop.find("value").text, "0.1")
  471. self.assertEqual(prop.find("type").text, "float")
  472. self.assertEqual(prop.find("uncertainty").text, "0.05")
  473. self.assertEqual(prop.find("unit").text, "mV")
  474. self.assertEqual(prop.find("value_origin").text, "raw.txt")
  475. self.assertEqual(prop.find("reference").text, "Value reference")
  476. self.assertEqual(len(prop.findall("filename")), 0)
  477. # Test valid multiple Value tag export
  478. prop = sec.findall("property")[4]
  479. self.assertEqual(len(prop), 7)
  480. self.assertEqual(prop.find("value").text, "[0.1,0.2,3]")
  481. self.assertEqual(prop.find("type").text, "float")
  482. self.assertEqual(prop.find("uncertainty").text, "0.05")
  483. self.assertEqual(prop.find("unit").text, "mV")
  484. self.assertEqual(prop.find("value_origin").text, "raw.txt")
  485. self.assertEqual(prop.find("reference").text, "Value reference")
  486. # Test non-export of invalid Value tags
  487. prop = sec.findall("property")[5]
  488. self.assertEqual(len(prop), 1)
  489. self.assertEqual(len(prop.findall("name")), 1)
  490. # Test dtype 'binary' replacement
  491. prop = sec.findall("property")[6]
  492. self.assertEqual(prop.find("name").text, "Unsupported binary value type replace")
  493. self.assertEqual(prop.find("type").text, "text")
  494. prop = sec.findall("property")[7]
  495. self.assertEqual(prop.find("name").text, "Unsupported binary value dtype replace")
  496. self.assertEqual(prop.find("type").text, "text")
  497. # Test single string value with commata
  498. prop = sec.findall("property")[8]
  499. self.assertEqual(prop.find("name").text, "testSingleString")
  500. self.assertEqual(prop.find("value").text,
  501. "Single, string, value, with, many, commata.")
  502. # Test string list import
  503. prop = sec.findall("property")[9]
  504. self.assertEqual(prop.find("name").text, "testStringList")
  505. self.assertEqual(prop.find("value").text, "[A,B,C]")
  506. # Test single string values wrapping whitespace removal
  507. prop = sec.findall("property")[10]
  508. self.assertEqual(prop.find("name").text, "testStringWhiteSpace")
  509. self.assertEqual(prop.find("value").text,
  510. "Single string value with wrapping whitespace")
  511. # Test multiple string values with wrapping whitespace removal
  512. prop = sec.findall("property")[11]
  513. self.assertEqual(prop.find("name").text, "testStringListWhiteSpace")
  514. self.assertEqual(prop.find("value").text,
  515. "[Multiple Strings,with wrapping,Whitespace]")
  516. # Test multiple int values with wrapping whitespaces
  517. prop = sec.findall("property")[12]
  518. self.assertEqual(prop.find("name").text, "testIntListWhiteSpace")
  519. self.assertEqual(prop.find("type").text, "int")
  520. self.assertEqual(prop.find("value").text, "[1,2,3]")
  521. def test_parse_dict_document(self):
  522. # Test appending tags; not appending empty sections
  523. doc_dict = {'Document': {'author': 'HPL', 'sections': []}}
  524. root = self.VC("")._parse_dict_document(doc_dict).getroot()
  525. self.assertEqual(len(root.getchildren()), 1)
  526. self.assertIsNotNone(root.find("author"))
  527. # Test appending multiple sections
  528. doc_dict = {'Document': {'author': 'HPL', 'sections': [{'name': 'sec_one'},
  529. {'name': 'sec_two'}]}}
  530. root = self.VC("")._parse_dict_document(doc_dict).getroot()
  531. self.assertEqual(len(root.getchildren()), 3)
  532. self.assertEqual(len(root.findall("section")), 2)
  533. def test_parse_dict_sections(self):
  534. # Test appending tags; not appending empty subsections or properties
  535. root = ET.Element("root")
  536. sec_dict = [{'name': 'sec_one', 'sections': [], 'properties': []}]
  537. self.assertEqual(len(root.getchildren()), 0)
  538. self.VC("")._parse_dict_sections(root, sec_dict)
  539. self.assertEqual(len(root.getchildren()), 1)
  540. self.assertIsNotNone(root.find("section").find("name"))
  541. # Test appending multiple sections
  542. root = ET.Element("root")
  543. sec_dict = [{'name': 'sec_one'}, {'name': 'sec_two'}, {'name': 'sec_three'}]
  544. self.assertEqual(len(root.getchildren()), 0)
  545. self.VC("")._parse_dict_sections(root, sec_dict)
  546. self.assertEqual(len(root.getchildren()), 3)
  547. # Test appending subsections
  548. root = ET.Element("root")
  549. sec_dict = [{'name': 'sec_one', 'sections': [{'name': 'sub_one'},
  550. {'name': 'sub_two'}]}]
  551. self.assertEqual(len(root.getchildren()), 0)
  552. self.VC("")._parse_dict_sections(root, sec_dict)
  553. sec = root.find("section")
  554. self.assertEqual(len(sec.getchildren()), 3)
  555. self.assertEqual(len(sec.findall("section")), 2)
  556. # Test appending properties
  557. root = ET.Element("root")
  558. sec_dict = [{'name': 'sec_one', 'properties': [{'name': 'prop_one'},
  559. {'name': 'prop_two'}]}]
  560. self.assertEqual(len(root.getchildren()), 0)
  561. self.VC("")._parse_dict_sections(root, sec_dict)
  562. sec = root.find("section")
  563. self.assertEqual(len(sec.getchildren()), 3)
  564. self.assertEqual(len(sec.findall("property")), 2)
  565. def test_parse_dict_properties(self):
  566. # Test appending tags and moving values
  567. root = ET.Element("root")
  568. prop_dict = [{'name': 'prop_one', 'values': [{'unit': 'none'},
  569. {'value': '1'}]}]
  570. self.assertEqual(len(root.getchildren()), 0)
  571. self.VC("")._parse_dict_properties(root, prop_dict)
  572. self.assertEqual(len(root.getchildren()), 1)
  573. self.assertIsNotNone(root.find("property"))
  574. prop = root.find("property")
  575. self.assertEqual(len(prop.getchildren()), 3)
  576. self.assertIsNotNone(prop.find("name"))
  577. self.assertEqual(len(prop.findall("value")), 2)
  578. # Test multiple entries
  579. root = ET.Element("root")
  580. prop_dict = [{'name': 'prop_one'},
  581. {'name': 'prop_two'}]
  582. self.assertEqual(len(root.getchildren()), 0)
  583. self.VC("")._parse_dict_properties(root, prop_dict)
  584. self.assertEqual(len(root.getchildren()), 2)
  585. def test_parse_dict_values(self):
  586. root = ET.Element("root")
  587. val_dict = [{'unit': 'arbitrary', 'value': "['one', 'two']"},
  588. {'unit': 'mV', 'value': '1'}]
  589. self.VC("")._parse_dict_values(root, val_dict)
  590. self.assertEqual(len(root.getchildren()), 2)
  591. for val in root.iterchildren():
  592. self.assertEqual(val.tag, "value")
  593. self.assertEqual(len(val.getchildren()), 1)
  594. self.assertIsNotNone(val.find("unit"))
  595. self.assertIsNotNone(val.text)
  596. def test_handle_repository(self):
  597. repo = ET.Element("repository")
  598. # Test working and valid repository link
  599. repo.text = '/'.join([REPOSITORY_BASE, 'v1.1', 'analysis', 'analysis.xml'])
  600. vc = self.VC("")
  601. self.assertIsNone(vc._handle_repository(repo))
  602. self.assertEqual(vc.conversion_log, [])
  603. # Test replaced working repository link
  604. repo.text = '/'.join([REPOSITORY_BASE, 'v1.0', 'analysis', 'analysis.xml'])
  605. self.assertIsNone(vc._handle_repository(repo))
  606. self.assertEqual(repo.text, '/'.join([REPOSITORY_BASE, 'v1.1',
  607. 'analysis', 'analysis.xml']))
  608. self.assertEqual(len(vc.conversion_log), 1)
  609. self.assertTrue("[Info]" in vc.conversion_log[0])
  610. # Test invalid repository link
  611. invalid = "I am leading nowhere"
  612. repo.text = invalid
  613. self.assertIsNone(vc._handle_repository(repo))
  614. self.assertEqual(len(vc.conversion_log), 2)
  615. self.assertTrue("[Warning]" in vc.conversion_log[1])
  616. self.assertEqual(repo.text, invalid)
  617. def test_handle_include(self):
  618. repo = ET.Element("include")
  619. # Test working and valid repository link
  620. repo.text = '/'.join([REPOSITORY_BASE, 'v1.1', 'analysis', 'analysis.xml'])
  621. vc = self.VC("")
  622. self.assertIsNone(vc._handle_include(repo))
  623. self.assertEqual(vc.conversion_log, [])
  624. # Test replaced working repository link
  625. repo.text = '/'.join([REPOSITORY_BASE, 'v1.0', 'analysis', 'analysis.xml'])
  626. self.assertIsNone(vc._handle_include(repo))
  627. self.assertEqual(repo.text, '/'.join([REPOSITORY_BASE, 'v1.1',
  628. 'analysis', 'analysis.xml']))
  629. self.assertEqual(len(vc.conversion_log), 1)
  630. self.assertTrue("[Info]" in vc.conversion_log[0])
  631. # Test invalid repository link
  632. invalid = "I am leading nowhere"
  633. repo.text = invalid
  634. self.assertIsNone(vc._handle_include(repo))
  635. self.assertEqual(len(vc.conversion_log), 2)
  636. self.assertTrue("[Warning]" in vc.conversion_log[1])
  637. self.assertEqual(repo.text, invalid)
  638. def test_convert_xml_file(self):
  639. # Test minimal reading from an xml file.
  640. basefile = os.path.join(self.basepath, "version_conversion.xml")
  641. root = self.VC(basefile)._parse_xml().getroot()
  642. self.assertIsNotNone(root.find("section"))
  643. sec = root.find("section")
  644. self.assertIsNotNone(sec.find("name"))
  645. self.assertIsNotNone(sec.find("type"))
  646. self.assertIsNotNone(sec.find("section").find("name"))
  647. self.assertIsNotNone(sec.find("property"))
  648. prop = sec.find("property")
  649. self.assertIsNotNone(prop.find("name"))
  650. self.assertIsNotNone(prop.find("value"))
  651. def test_convert_yaml_file(self):
  652. # Test minimal reading from a yaml file.
  653. basefile = os.path.join(self.basepath, "version_conversion.yaml")
  654. root = self.VC(basefile)._parse_yaml().getroot()
  655. self.assertIsNotNone(root.find("section"))
  656. sec = root.find("section")
  657. self.assertIsNotNone(sec.find("name"))
  658. self.assertIsNotNone(sec.find("type"))
  659. self.assertIsNotNone(sec.find("section"))
  660. self.assertIsNotNone(sec.find("property"))
  661. prop = sec.find("property")
  662. self.assertIsNotNone(prop.find("name"))
  663. self.assertIsNotNone(prop.find("value"))
  664. def test_convert_json_file(self):
  665. # Test minimal reading from a json file.
  666. basefile = os.path.join(self.basepath, "version_conversion.json")
  667. root = self.VC(basefile)._parse_json().getroot()
  668. self.assertIsNotNone(root.find("section"))
  669. sec = root.find("section")
  670. self.assertIsNotNone(sec.find("name"))
  671. self.assertIsNotNone(sec.find("type"))
  672. self.assertIsNotNone(sec.find("section"))
  673. self.assertIsNotNone(sec.find("property"))
  674. prop = sec.find("property")
  675. self.assertIsNotNone(prop.find("name"))
  676. self.assertIsNotNone(prop.find("value"))
  677. def test_write_to_file(self):
  678. infile = os.path.join(self.basepath, "version_conversion.xml")
  679. self.tmp_dir = tempfile.mkdtemp(suffix=".odml")
  680. # Test write to named file
  681. outfile = os.path.join(self.tmp_dir, "test.odml")
  682. self.VC(infile).write_to_file(outfile)
  683. self.assertTrue(os.path.exists(outfile))
  684. # Test file extension append write to named file w/o file extension
  685. outfile = os.path.join(self.tmp_dir, "test")
  686. self.VC(infile).write_to_file(outfile)
  687. self.assertFalse(os.path.exists(outfile))
  688. self.assertTrue(os.path.exists("%s.xml" % outfile))