示例#1
0
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))
示例#2
0
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)
示例#3
0
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)
示例#4
0
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())