123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- import odml
- import unittest
- import os
- import sys
- import re
- from odml.tools import xmlparser
- from odml.tools import jsonparser
- from odml.tools import dumper
- def dump(doc, filename):
- """
- helper function to dump a document for debugging purposes
- """
- if sys.version_info < (3, 0):
- odml_string = unicode(xmlparser.XMLWriter(doc))
- else:
- odml_string = str(xmlparser.XMLWriter(doc))
- open(filename, "w").write(odml_string)
-
- def parse(data):
- """
- parses strings to quickly create odml-documents
-
- e.g.:
- s1[t1] mapping [T1]
- - p1
- s2[t1]
- - s21[t2] linked to /s1/s2
- """
- lines = data.strip(" ").strip("\n").split("\n")
- offset = len(re.compile('(\s*)').match(lines[0]).group())
- pat = re.compile(r'(?P<name>\w+)(\[(?P<type>\w+)\])?(\s+mapping \[(?P<dst>[\w:]+)\])?(\s+linked to (?P<link>[\w/]+))?')
- parents = [odml.Document(), None]
- for line in lines:
- line = line[offset:]
- while len(parents) > 1:
- parpref =(len(parents)-2)*2
- if line.startswith(" " * parpref):
- line = line[parpref:]
- break
- parents.pop()
- if line.startswith('- '):
- line = line[2:]
- else:
- parents.pop()
- try:
- m = pat.match(line).groupdict()
- except:
- print("error parsing", repr(line))
- raise
- if m['type'] is None:
- obj = odml.Property(name=m['name'], value="[val]")
- else:
- obj = odml.Section(name=m['name'], type=m['type'])
- if m['dst'] is not None:
- obj.mapping = 'map#%s' % m['dst']
- if m['link'] is not None:
- obj._link = m['link']
- parents[-1].append(obj)
- parents.append(obj)
- return parents[0]
- class SampleFileCreator:
- def create_document(self):
- doc = odml.Document()
- for i in range(3):
- doc.append(self.create_section("sec %d" % i))
- return doc
- def create_section(self, name, depth=0):
- s = odml.Section(name=name, type=name.replace("sec", "type"))
- if depth < 1:
- for i in range(2):
- s.append(self.create_section("%s,%d" % (name, i), depth=depth+1))
- if name.endswith("1"):
- for i in range(3):
- s.append(self.create_property("%s:%d" % (name, i)))
- return s
- def create_property(self, name):
- value = self.create_value(name.replace("sec", "val"))
- return odml.Property(name=name.replace("sec", "prop"), value=value)
- def create_value(self, content):
- return odml.Value(content)
- class SampleFileCreatorTest(unittest.TestCase):
- def test_samplefile(self):
- doc = SampleFileCreator().create_document()
- # dumper.dumpDoc(doc)
- class SampleFileOperationTest(unittest.TestCase):
- def setUp(self):
- doc = SampleFileCreator().create_document()
- doc.sections['sec 0'].sections['sec 0,1'].type = "test"
- self.doc = doc
- def test_find_key(self):
- self.assertEqual(self.doc.find(key="sec 1,1"), None)
- # find distant child
- sec = self.doc.find_related(key="sec 1,1")
- self.assertEqual(sec.name, "sec 1,1")
- # find sibling
- res = sec.find_related(key="sec 0,0")
- self.assertEqual(res, None)
- sec = sec.find_related(key="sec 1,0")
- self.assertEqual(sec.name, "sec 1,0")
- # find parent
- res = sec.find_related(key="sec 0")
- self.assertEqual(res, None)
- sec = sec.find_related(key="sec 1")
- self.assertEqual(sec.name, "sec 1")
- # find section by type
- self.assertEqual(self.doc.find_related(type="test").name, "sec 0,1")
- def test_xml_writer_version(self):
- doc = odml.Document()
- if sys.version_info < (3, 0):
- val = unicode(xmlparser.XMLWriter(doc))
- else:
- val = str(xmlparser.XMLWriter(doc))
- self.assertIn('version="%s"' % xmlparser.XML_VERSION, val)
- doc = xmlparser.XMLReader().fromString(val)
- # this test is switched off until the XML versioning support is implemented
- # self.assertEqual(doc._xml_version, xmlparser.XML_VERSION)
- def test_save(self):
- for module in [xmlparser.XMLWriter, jsonparser.JSONWriter]:
- doc = module(self.doc)
- import tempfile
- path = tempfile.gettempdir()
- path = os.path.join(path, "temp.odml")
- doc.write_file(path)
- os.unlink(path)
- def test_restore(self):
- try:
- from StringIO import StringIO
- except ImportError:
- from io import StringIO
- for Writer, Reader in [(xmlparser.XMLWriter, xmlparser.XMLReader),
- (jsonparser.JSONWriter, jsonparser.JSONReader)]:
- doc = Writer(self.doc)
- if sys.version_info < (3, 0):
- doc = StringIO(unicode(doc))
- else:
- doc = StringIO(str(doc))
- doc = Reader().fromFile(doc)
- self.assertEqual(doc, self.doc)
- # for a,b in zip(doc.sections, self.doc.sections):
- # print "sec cmp", a, b
- # self.assertEqual(a, b)
- # print "A ---------------------------------"
- # for sec in doc.sections:
- # xmlparser.dumpSection(sec)
- # print "B ---------------------------------"
- # for sec in self.doc.sections:
- # xmlparser.dumpSection(sec)
- # print "-----------------------------------"
- class AttributeTest(unittest.TestCase):
- def test_value_int(self):
- v = odml.Value(value="1", dtype="int")
- self.assertEqual(v.data, 1)
- def test_conversion_int_to_float(self):
- v = odml.Value(value="1", dtype="int")
- v.dtype = "float" # change dtype
- self.assertEqual(v.dtype, "float")
- self.assertEqual(v.data, 1.0)
- self.assertEqual(v.value, "1.0")
- def test_conversion_float_to_int(self):
- v = odml.Value(value="1.5", dtype="float")
- v.dtype = "int"
- self.assertEqual(v.dtype, "int")
- self.assertEqual(v.data, 1)
- def test_value_float(self):
- v = odml.Value(value="1.5", dtype="float")
- self.assertEqual(v.data, 1.5)
- class CopyTest(unittest.TestCase):
- def setUp(self):
- self.p = odml.Property(name="test", value=1)
- def test_dependence(self):
- a = self.p
- b = self.p
- self.assertEqual(a, b)
- a.value = odml.Value(5)
- self.assertEqual(a, b)
- self.assertEqual(a.value, b.value)
- def test_independence(self):
- a = self.p.clone()
- b = self.p.clone()
- self.assertEqual(a, b)
- a.value = odml.Value(5)
- self.assertNotEqual(a, b)
- # self.assertUn
- class MiscTest(unittest.TestCase):
- def setUp(self):
- self.doc = SampleFileCreator().create_document()
- def test_paths(self):
- sec = odml.Section("bar")
- self.assertEqual(sec._get_relative_path("/a", "/b"), "/b")
- self.assertEqual(sec._get_relative_path("/a", "/a/b"), "b")
- self.assertEqual(sec._get_relative_path("/a/b", "/a/c"), "../c")
- self.assertEqual(sec._get_relative_path("/a/b/c", "/a"), "../..")
- self.assertEqual(sec._get_relative_path("/a/b", "/a"), "..")
- def test_section_path(self):
- sec1 = self.doc.sections[1]
- sec10 = sec1.sections[0]
- sec11 = sec1.sections[1]
- path = sec10.get_path()
- self.assertEqual(path, "/%s/%s" % (sec1.name, sec10.name))
- self.assertEqual(self.doc.get_path(), "/")
- self.assertEqual(sec10.get_relative_path(sec1), "..")
- path_to_sec10 = sec1.get_relative_path(sec10)
- self.assertEqual(path_to_sec10, sec10.name)
- self.assertIs(sec1.get_section_by_path(path_to_sec10), sec10)
- path_to_sec11 = sec10.get_relative_path(sec11)
- self.assertEqual(path_to_sec11, "../" + sec11.name)
- self.assertIs(sec10.get_section_by_path(path_to_sec11), sec11)
- def test_findall_related(self):
- doc = parse("""
- s1[T1]
- - s2[T1]
- """)
- self.assertEqual(len(doc.find_related(type="T1", findAll=True)), 2)
- doc = parse("""
- s0[T1]
- - s00[T2]
- s1[T2]
- s2[T1]
- """)
- self.assertEqual(len(doc.sections[1].find_related(type="T1", findAll=True)), 2)
- def test_reorder_post(self):
- old_index = self.doc.sections[0].reorder(2)
- self.assertEqual(old_index, 0)
- self.assertEqual(self.doc.sections[0].name, "sec 1")
- self.assertEqual(self.doc.sections[1].name, "sec 2")
- self.assertEqual(self.doc.sections[2].name, "sec 0")
- def test_reorder_first(self):
- old_index = self.doc.sections[2].reorder(0)
- self.assertEqual(old_index, 2)
- self.assertEqual(self.doc.sections[0].name, "sec 2")
- self.assertEqual(self.doc.sections[1].name, "sec 0")
- self.assertEqual(self.doc.sections[2].name, "sec 1")
- def test_get_section_by_path(self):
- sec0 = self.doc.sections[0]
- sec1 = self.doc.sections[1]
- sec01 = sec0.sections[1]
- sec10 = sec1.sections[0]
- sec11 = sec1.sections[1]
- # test absolute path
- current = self.doc.get_section_by_path(sec10.get_path())
- self.assertEqual(current, sec10)
- # test relative path with ../
- current = sec10.get_section_by_path(sec10.get_relative_path(sec11))
- self.assertEqual(current, sec11)
- # test relative path with ./
- current = sec1.get_section_by_path("./" + sec1.get_relative_path(sec11))
- self.assertEqual(current, sec11)
- # test relative path
- current = sec1.get_section_by_path(sec1.get_relative_path(sec11))
- self.assertEqual(current, sec11)
- # test wrong parent
- wrongpath = "../" + sec10.get_relative_path(sec11)
- self.assertRaises(ValueError, sec10.get_section_by_path, wrongpath)
- # test wrong child
- wrongpath = sec1.get_relative_path(sec10) + "/foo"
- self.assertRaises(ValueError, sec1.get_section_by_path, wrongpath)
- # test absolute path with no document
- newsec = SampleFileCreator().create_section("foo", 0)
- path = newsec.sections[0].get_path()
- self.assertRaises(ValueError, newsec.sections[1].get_section_by_path, path)
- # test path with property is invalid
- path = sec11.properties[0].get_path()
- self.assertRaises(ValueError, self.doc.get_section_by_path, path)
- def test_get_property_by_path(self):
- sec0 = self.doc.sections[0]
- sec1 = self.doc.sections[1]
- sec00 = self.doc.sections[0].sections[0]
- sec11 = self.doc.sections[1].sections[1]
- sec10 = self.doc.sections[1].sections[0]
- prop = sec11.properties[0]
- # test absolute path from document
- current = self.doc.get_property_by_path(prop.get_path())
- self.assertEqual(current, prop)
- # test absolute path from section
- current = sec00.get_property_by_path(prop.get_path())
- self.assertEqual(current, prop)
- # test relative path from section
- manualpath = "../%s/%s:%s" % (sec1.name, sec11.name, prop.name)
- current = sec0.get_property_by_path(manualpath)
- self.assertEqual(current, prop)
- # test non-existing property
- wrongpath = sec10.get_relative_path(sec11) + ":foo"
- self.assertRaises(ValueError, sec1.get_property_by_path, wrongpath)
- # test path with section is invalid
- wrongpath = sec11.get_path()
- self.assertRaises(ValueError, sec1.get_property_by_path, wrongpath)
- def test_save_version(self):
- self.doc.version = '2.4'
- writer = xmlparser.XMLWriter(self.doc)
- writer.write_file("/tmp/example.odml")
- restored = xmlparser.load("/tmp/example.odml")
- self.assertEqual(self.doc.version, restored.version)
- if __name__ == '__main__':
- import sys
- if len(sys.argv) > 1 and sys.argv[1] == "--dump":
- dump(SampleFileCreator().create_document(), sys.argv[2])
- sys.exit(0)
- unittest.main()
|