class TestTypeMagic(unittest.TestCase): def setUp(self): self.connection = Connection.test() self.connection.create_tables() self.m = Mapper(self.connection) def tearDown(self): self.connection.drop_tables() # need to dispose manually to avoid too many connections error self.connection.engine.dispose() def test_rebrand(self): class E0(Entity): declared_params = { "q": "integer" } class E1(Entity): declared_params = { "q": "integer", "q1": "integer" } e0 = E0(q=100) self.m.save(e0) self.m.rebrand(E0, E1) # trying to load something from e0 now raises self.assertRaises(DetachedInstanceError, lambda: e0.type) self.assertRaises(DetachedInstanceError, lambda: dict(e0.params)) # lazy, so we call dict e1 = self.m.find_roots()[0] #self.m.session.expunge(e1) import pdb #pdb.set_trace() self.assertEqual(e1._type, E1.__name__) self.assertEqual(e1.params["q"], 100) e1.params["q"] = 0 e1.params["q1"] = 0 def test_multi_step_rebrand(self): class MyEntity1(Entity): declared_params = { "name": "string", "version": "integer" } class MyEntity2a(Entity): declared_params = { "name": "string", "version": "integer", "version_string": "string", "release_date": "date" } class MyEntity2b(Entity): declared_params = { "name": "string", "version_string": "string", "release_date": "date" } class MyEntity3(Entity): declared_params = { "name": "string", "version": "string", "release_date": "date" } orig_entities = [ MyEntity1(name="abc", version=1), MyEntity1(name="def", version=2), MyEntity1(name="ghi", version=3), MyEntity1(name="jkl", version=4), MyEntity1(name="mno", version=5), MyEntity1(name="pqr", version=6), MyEntity1(name="stu", version=7) ] self.m.save(*orig_entities) def change_version_string_add_date(e, params): params["version_string"] = str(params["version"]) del params["version"] params["release_date"] = datetime.date.today() return params def change_version_string(e, params): params["version"] = params["version_string"] del params["version_string"] return params self.assertEqual(len(self.m.find(MyEntity1).all()), 7) self.assertEqual(len(self.m.find(MyEntity3).all()), 0) version_1 = [e.params["version"] for e in self.m.find(MyEntity1)] self.assertEqual(len(version_1), 7) self.assertTrue(all(type(v)==int for v in version_1)) # we cannot rebrand directly: self.assertRaises(ValueError, self.m.rebrand, MyEntity1, MyEntity3) # do the rebranding self.m.rebrand(MyEntity1, MyEntity2a, after=change_version_string_add_date) # still won’t work to do this directly self.assertRaises(ValueError, self.m.rebrand, MyEntity2a, MyEntity3) self.m.rebrand(MyEntity2a, MyEntity2b) self.m.rebrand(MyEntity2b, MyEntity3, after=change_version_string) self.assertEqual(len(self.m.find(MyEntity1).all()), 0) self.assertEqual(len(self.m.find(MyEntity3).all()), 7) version_3 = [e.params["version"] for e in self.m.find(MyEntity3)] self.assertEqual(len(version_3), 7) self.assertTrue(all(isinstance(v, basestring) for v in version_3))
class TestXml(unittest.TestCase): test_xml = """<?xml version="1.0" ?> <xdapy><values> <entity id="1" type="Experiment"> <data encoding="base64" name="hlkk"> bGtqbGtqa2wjw6Rqa2xqeXNkc2E= </data> <parameter name="project" type="string" value="PPP0"/> <parameter name="experimenter" type="string" value="John Do"/> <entity id="4" type="Observer" parent="id:1"> <parameter name="age" type="integer" value="26"/> <parameter name="handedness" type="string" value="right"/> <parameter name="name" type="string" value="Max Mustermann"/> </entity> </entity> <entity id="2" type="Session"> <parameter name="date" type="date" value="2010-12-21"/> </entity> <entity id="3" type="Experiment"> <parameter name="project" type="string" value="PPP1"/> <parameter name="experimenter" type="string" value="John Doe"/> </entity> <entity id="5" type="Observer"> <parameter name="age" type="integer" value="38"/> <parameter name="handedness" type="string" value="left"/> <parameter name="name" type="string" value="Susanne Sorgenfrei"/> </entity> <entity id="6" type="Observer"> <parameter name="age" type="integer" value="40"/> <parameter name="handedness" type="string" value="left"/> <parameter name="name" type="string" value="Susi Sorgen"/> </entity> <entity id="7" type="Session"> <parameter name="date" type="date" value="2010-12-21"/> </entity> </values> <relations> <context name="Some Context" from="id:1" to="id:5" /> </relations> </xdapy>""" def setUp(self): """Create test database in memory""" self.connection = Connection.test() self.connection.create_tables() self.mapper = Mapper(self.connection) self.mapper.register(*objects) def tearDown(self): # need to dispose manually to avoid too many connections error self.connection.drop_tables() self.connection.engine.dispose() def testXml(self): xmlio = XmlIO(self.mapper) xmlio.read(self.test_xml) objs = self.mapper.find_all(Entity) roots = self.mapper.find_roots() self.assertEqual(len(objs), 7) self.assertEqual(len(roots), 6) def test_unique_id(self): test_xml = wrap_xml_values("""<entity id="1" type="Experiment" unique_id="2" />""") xmlio = XmlIO(self.mapper) xmlio.read(test_xml) def test_undefined_type(self): test_xml = """<xdapy><types> <entity name="Experiment" /> </types></xdapy>""" xmlio = XmlIO(self.mapper) self.assertRaises(UnregisteredTypesError, xmlio.read, test_xml) def test_type_name_twice(self): class Experiment(Entity): declared_params = {"project": "string"} test_xml = """<xdapy><types> <entity name="Experiment"> <parameter name="project" type="string"/> <parameter name="experimenter" type="string"/> </entity> <entity name="Experiment"> <parameter name="project" type="string"/> </entity> </types></xdapy>""" objects = self.mapper.registered_entities objects.append(Experiment) xmlio = XmlIO(self.mapper, objects) self.assertRaises(AmbiguousObjectError, xmlio.read, test_xml) def test_same_type_defined_twice(self): test_xml = """<xdapy><types> <entity name="Experiment"> <parameter name="project" type="string"/> <parameter name="experimenter" type="string"/> </entity> <entity name="Experiment"> <parameter name="project" type="string"/> <parameter name="experimenter" type="string"/> </entity> </types></xdapy>""" xmlio = XmlIO(self.mapper) xmlio.read(test_xml) def test_wrong_parameter(self): test_xml = """<xdapy><types> <entity name="Experiment"> <parameter name="s" type="string" /> </entity> </types></xdapy>""" xmlio = XmlIO(self.mapper) self.assertRaises(UnregisteredTypesError, xmlio.read, test_xml) def test_wrong_parameter_type(self): test_xml = """<xdapy><types> <entity name="Experiment"> <parameter name="project" type="strong" /> </entity> </types></xdapy>""" xmlio = XmlIO(self.mapper) self.assertRaises(UnregisteredTypesError, xmlio.read, test_xml) def test_invalid_type_entity(self): test_xml = """<xdapy><types> <entty name="Experiment"> <parameter name="project" type="strong" /> </entty> </types></xdapy>""" xmlio = XmlIO(self.mapper) self.assertRaises(InvalidInputError, xmlio.read, test_xml)
class TestJson(unittest.TestCase): def setUp(self): """Create test database in memory""" self.connection = Connection.test() self.connection.create_tables() self.mapper = Mapper(self.connection) def tearDown(self): self.connection.drop_tables() # need to dispose manually to avoid too many connections error self.connection.engine.dispose() def test_null_import(self): json = """ { "types": [], "objects": [], "relations": [] }""" jio = JsonIO(self.mapper) objs = jio.read_string(json) self.assertEqual(len(objs), 0) def test_unknown_types(self): json = """ { "types": [{"type": "A"}, {"type": "B"}], "objects": [{"type": "A"}, {"type": "A"}, {"type": "A"}, {"type": "B"}], "relations": [] }""" jio = JsonIO(self.mapper) self.assertRaises(InvalidInputError, jio.read_string, json) def test_simple_import(self): json = """ { "types": [{"type": "A"}, {"type": "B"}], "objects": [{"type": "A"}, {"type": "A"}, {"type": "A"}, {"type": "B"}], "relations": [] }""" jio = JsonIO(self.mapper, add_new_types=True) objs = jio.read_string(json) self.assertEqual(len(objs), 4) def test_parameters(self): json = """ { "types": [ { "type": "A", "parameters": { "s": "string", "d": "datetime", "i": "integer" } } ], "objects": [ { "type": "A", "parameters": { "s": "string", "d": "2012-02-10T20:00:00", "i": 12 } }, { "type": "A" }, { "type": "A" } ], "relations": [] }""" jio = JsonIO(self.mapper, add_new_types=True) objs = jio.read_string(json) self.assertEqual(len(objs), 3) self.assertEqual(objs[0].params["s"], "string") self.assertEqual(objs[0].params["d"], datetime.datetime(2012, 2, 10, 20, 0, 0)) self.assertEqual(objs[0].params["i"], 12) def test_parameters_as_dict(self): json = { "types": [ { "type": "A", "parameters": { "s": "string", "d": "datetime" } } ], "objects": [ { "type": "A", "parameters": { "s": "string", "d": "2012-02-10T20:00:00" } }, { "type": "A", "parameters": { "d": datetime.datetime(2012, 2, 10, 20, 0, 0) }}, { "type": "A" } ], "relations": [] } jio = JsonIO(self.mapper, add_new_types=True) objs = jio.read_json(json) self.assertEqual(len(objs), 3) self.assertEqual(objs[0].params["s"], "string") self.assertEqual(objs[0].params["d"], datetime.datetime(2012, 2, 10, 20, 0, 0)) def test_children(self): json = { "types": [{ "type": "A", "parameters": { "s": "string" } }], "objects": [ { "type": "A", "id": 1, "parameters": { "s": "parent1" } }, { "type": "A", "parameters": { "s": "parent2" }, "children": [ { "type": "A", "parameters": { "s": "child21" } }, { "type": "A", "parameters": { "s": "child22" } }, ] }, { "type": "A", "id": 2, "parameters": { "s": "child11" } } ], "relations": [ { "relation": "child", "from": "id:2", "to": "id:1" } ] } jio = JsonIO(self.mapper, add_new_types=True) objs = jio.read_json(json) self.assertEqual(len(objs), 5) roots = self.mapper.find_roots() self.assertEqual(set([roots[0].params["s"], roots[1].params["s"]]), set(["parent1", "parent2"])) def test_data_export(self): class SomeEntity(Entity): declared_params = {"some_value": "string"} obj = SomeEntity() self.mapper.register(SomeEntity) self.mapper.save(obj) data_to_save = [("some key", "ABCDE", None), ("some other key", "ABCDEFGHIJ", "text")] for (key, value, mimetype) in data_to_save: obj.data[key].put(value) if mimetype: obj.data[key].mimetype = mimetype # we create a named temporary file and just hope # there is no conflict with the autodetected folder name tmp_name = tempfile.mktemp() jio = JsonIO(self.mapper, add_new_types=True) jio.write_file(self.mapper.find_roots(), tmp_name) # check that file has been written: for (data_key, data_value, data_mimetype) in data_to_save: data_file = os.path.join(tmp_name + ".data", obj.unique_id, data_key) with open(data_file) as df: self.assertEqual(df.read(), data_value) with open(tmp_name) as tmp_file: json_obj = json.load(tmp_file) #print json_obj jio_2 = JsonIO(self.mapper) self.assertRaises(IntegrityError, jio_2.read_file, tmp_name) self.mapper.delete(*self.mapper.find_roots()) jio_2 = JsonIO(self.mapper) jio_2.read_file(tmp_name) obj_in_db = self.mapper.find_first(SomeEntity) for (data_key, data_value, data_mimetype) in data_to_save: self.assertEqual(obj_in_db.data[data_key].get_string(), data_value) self.assertEqual(obj_in_db.data[data_key].mimetype, data_mimetype)
from xdapy.structures import Context from sqlalchemy.orm.exc import NoResultFound def migrate_connections(m1, m2): conn1 = m1.find(Context) for c1 in conn1: from_unique_id = c1.holder.unique_id to_unique_id = c1.attachment.unique_id name = c1.connection_type print from_unique_id, to_unique_id try: m2_from = m2.find_by_unique_id(from_unique_id) m2_to = m2.find_by_unique_id(to_unique_id) m2_from.attach(name, m2_to) except NoResultFound: pass migrate(m, m_2, mapping) migrate(m_2, m, mapping) migrate_connections(m, m_2) print m.find_roots() print m_2.find_roots() assert len(m.find_roots()) == len(m_2.find_roots())