def test_cycles_allowed(self):

        from cocktail.schema import Reference, exceptions

        # Valid relations
        a = {"rel": None}
        b = {"rel": a}

        # 'c' contains itself
        c = {"rel": None}
        c["rel"] = c

        # 'd' and 'e' form a cycle
        d = {"rel": None}
        e = {"rel": None}
        d["rel"] = e
        e["rel"] = d

        # 'f' and 'h' form a cycle
        f = {"rel": None}
        g = {"rel": None}
        h = {"rel": None}
        f["rel"] = g
        g["rel"] = h
        h["rel"] = f

        self._test_validation(Reference("rel", cycles_allowed=False), [a, b],
                              [c, d, e, f, g, h],
                              exceptions.RelationCycleError)

        self._test_validation(Reference("rel", cycles_allowed=True),
                              [a, b, c, d, e, f, g, h])
    def test_one_to_one(self):

        from cocktail.schema import SchemaObject, Reference
        from cocktail.schema.exceptions import SchemaIntegrityError

        class Foo(SchemaObject):
            pass

        class Bar(SchemaObject):
            pass

        Foo.add_member(Reference("bar", type=Bar, bidirectional=True))
        Bar.add_member(Reference("foo", type=Foo, bidirectional=True))

        foo = Foo()
        bar = Bar()
        foo.bidirectional = False
        foo.bar = bar

        self.assertTrue(foo.bar is bar)
        self.assertTrue(bar.foo is None)

        bar.foo = foo
        self.assertTrue(bar.foo is foo)
        self.assertTrue(foo.bar is bar)

        foo.bidirectional = True
        foo.bar = None
        self.assertTrue(foo.bar is None)
        self.assertTrue(bar.foo is None)
Beispiel #3
0
    def test_implicit_cascade_delete(self):

        from cocktail.schema import Reference, Collection
        import cocktail.persistence  # load extension attributes

        ref = Reference(bidirectional=True, integral=True)

        self.assertTrue(ref.cascade_delete)

        collection = Reference(bidirectional=True, integral=True)

        self.assertTrue(collection.cascade_delete)
    def get_schema(self):

        from cocktail.schema import Schema, Reference, Collection

        schema = Schema()

        schema.add_member(Reference("parent", type=schema, bidirectional=True))

        schema.add_member(
            Collection("children",
                       items=Reference(type=schema),
                       bidirectional=True))

        return schema
    def test_match_one_to_one(self):

        from cocktail.schema import Schema, Reference
        from cocktail.schema.exceptions import SchemaIntegrityError

        a = Schema("a")
        b = Schema("b")

        a.add_member(Reference("rel_b", type=b, bidirectional=True))
        b.add_member(Reference("rel_a", type=a, bidirectional=True))

        self.assertTrue(a["rel_b"].related_end is b["rel_a"])
        self.assertTrue(a["rel_b"].related_type is b)
        self.assertTrue(b["rel_a"].related_end is a["rel_b"])
        self.assertTrue(b["rel_a"].related_type is a)
Beispiel #6
0
 class TestObject(PersistentObject):
     test_field = String(
         unique = True,
         indexed = True
     )
     parent = Reference(bidirectional = True)
     children = Collection(bidirectional = True)
Beispiel #7
0
    def test_delete_updates_self_contained_relation(self):

        from cocktail.schema import Reference, Collection
        from cocktail.persistence import PersistentObject

        class A(PersistentObject):
            pass

        class B(PersistentObject):
            pass

        A.add_member(
            Collection(
                "b",
                items = Reference(type = B),
                related_end = Collection()
            )
        )

        a = A()
        a.insert()

        b = B()
        b.insert()

        a.b.append(b)
        b.delete()

        assert not a.b
    def test_bidirectional_assignment(self):

        from cocktail.schema import Collection, Reference
        from cocktail.persistence import (
            PersistentObject, PersistentRelationOrderedSet
        )

        class Foo(PersistentObject):
            bar = Collection(bidirectional = True)

        class Bar(PersistentObject):
            foo = Reference(bidirectional = True)

        Foo.bar.items = Reference(type = Bar)
        Bar.foo.type = Foo

        foo = Foo()
        bar = foo.bar
        value = [Bar(), Bar()]
        foo.bar = value
        self.assertTrue(foo.bar is bar)
        self.assertTrue(isinstance(foo.bar, PersistentRelationOrderedSet))
        self.assertTrue(foo.bar.owner is foo)
        self.assertTrue(foo.bar.member is Foo.bar)
        self.assertEqual(list(foo.bar), value)
    def test_no_match(self):

        from cocktail.schema import Schema, Reference
        from cocktail.schema.exceptions import SchemaIntegrityError

        a = Schema("a")
        b = Schema("b")

        a.add_member(Reference("rel_b", type=b, bidirectional=True))
        b.add_member(Reference("rel_a", type=a))

        def resolve_relation():
            print(a["rel_b"].related_end)

        self.assertRaises(SchemaIntegrityError, resolve_relation)

        self.assertTrue(b["rel_a"].related_end is None)
Beispiel #10
0
    def test_match_many_to_many(self):

        from cocktail.schema import Schema, Reference, Collection
        from cocktail.schema.exceptions import SchemaIntegrityError

        a = Schema("a")
        b = Schema("b")

        a.add_member(
            Collection("rel_b", items=Reference(type=b), bidirectional=True))
        b.add_member(
            Collection("rel_a", items=Reference(type=a), bidirectional=True))

        self.assertTrue(a["rel_b"].related_end is b["rel_a"])
        self.assertTrue(a["rel_b"].related_type is b)
        self.assertTrue(b["rel_a"].related_end is a["rel_b"])
        self.assertTrue(b["rel_a"].related_type is a)
Beispiel #11
0
    def test_class_family(self):

        from cocktail.schema import Reference

        class Foo(object):
            pass

        class Bar(Foo):
            pass

        class Spam(object):
            pass

        ref = Reference(class_family=Foo)

        assert ref.validate(None)
        assert ref.validate(Foo)
        assert ref.validate(Bar)
        assert not ref.validate(Spam)
Beispiel #12
0
    def test_many_to_many(self):

        from cocktail.schema import SchemaObject, Reference, Collection
        from cocktail.schema.exceptions import SchemaIntegrityError

        class Container(SchemaObject):
            components = Collection(bidirectional=True, integral=True)

        class Component(SchemaObject):
            containers = Collection(bidirectional=True)

        Container.components.items = Reference(type=Component)
        Component.containers.items = Reference(type=Container)

        # 'integral' can't be set on an n:m relation
        def resolve_relation():
            Container.components.related_end

        self.assertRaises(SchemaIntegrityError, resolve_relation)
Beispiel #13
0
        class Document(PersistentObject):
            parent = Reference(
                bidirectional = True,
                related_key = "children"
            )
            children = Collection(
                bidirectional = True,
                related_key = "parent"
            )

            extension = Reference(
                bidirectional = True,
                related_key = "extended"
            )
            extended = Reference(
                bidirectional = True,
                related_key = "extension"
            )

            improvement = Reference()
            related_documents = Collection()
Beispiel #14
0
 def relation_selection(self):
     member = self.relation_member
     value = get_parameter(
         Collection(
             name = "relation_selection-" + member.name,
             items = Reference(type = member.related_type)
         )
     )
     if not value:
         return []
     else:
         enum = frozenset(self.stack_node.form_data.get(member.name))
         return [item for item in value if item in enum]
Beispiel #15
0
    def setUp(self):
        TempStorageMixin.setUp(self)

        from cocktail.schema import Reference, Collection
        from cocktail.persistence import PersistentObject, datastore

        datastore.root.clear()

        class Document(PersistentObject):
            parent = Reference(
                bidirectional = True,
                related_key = "children"
            )
            children = Collection(
                bidirectional = True,
                related_key = "parent"
            )

            extension = Reference(
                bidirectional = True,
                related_key = "extended"
            )
            extended = Reference(
                bidirectional = True,
                related_key = "extension"
            )

            improvement = Reference()
            related_documents = Collection()

        Document.extension.type = Document
        Document.extended.type = Document
        Document.parent.type = Document
        Document.children.items = Reference(type = Document)
        Document.improvement.type = Document
        Document.related_documents.items = Reference(type = Document)

        self.Document = Document
Beispiel #16
0
    def get_entities(self):

        from cocktail.schema import SchemaObject, Reference, Collection

        class Foo(SchemaObject):
            bar = Reference(bidirectional=True)

        class Bar(SchemaObject):
            foos = Collection(bidirectional=True)

        Foo.bar.type = Bar
        Bar.foos.items = Reference(type=Foo)

        return Foo, Bar
Beispiel #17
0
    def test_one_to_many(self):

        from cocktail.schema import SchemaObject, Reference, Collection
        from cocktail.schema.exceptions import SchemaIntegrityError

        class Foo(SchemaObject):
            pass

        class Bar(SchemaObject):
            pass

        Foo.add_member(Reference("bar", type=Bar, bidirectional=True))
        Bar.add_member(
            Collection("foos", items=Reference(type=Foo), bidirectional=True))

        foo = Foo()
        bar = Bar()
        foo.bidirectional = False
        foo.bar = bar

        self.assertTrue(foo.bar is bar)
        self.assertFalse(bar.foos)

        bar.foos = [foo]
        self.assertEqual(bar.foos, [foo])
        self.assertTrue(foo.bar is bar)

        foo.bidirectional = True
        foo.bar = None
        self.assertTrue(foo.bar is None)
        self.assertFalse(bar.foos)

        bar.bidirectional = False
        bar.foos = [foo]
        self.assertEqual(bar.foos, [foo])
        self.assertTrue(foo.bar is None)
    def test_reference_relation_constraints(self):

        from cocktail.schema import Reference, Integer, exceptions, get

        foreign_field = Integer("foo")

        ref = Reference(relation_constraints=[
            foreign_field.not_equal(None),
            foreign_field.greater(3),
            foreign_field.lower(8),
            lambda owner, related: get(related, "foo", None) is None or get(
                related, "foo", None) % 5 != 0
        ])

        self._test_validation(ref, [None, {"foo": 4}, {"foo": 6}, {"foo": 7}])

        self._test_validation(
            ref,
            None,
            [{}, {
                "foo": None
            }],
            exceptions.RelationConstraintError,
            error_count=2  # Note that x > None is always True
        )

        self._test_validation(ref, None, [{
            "foo": -6
        }, {
            "foo": 1
        }, {
            "foo": 3
        }], exceptions.RelationConstraintError,
                              {"constraint": ref.relation_constraints[1]})

        self._test_validation(ref, None, [{
            "foo": 8
        }, {
            "foo": 12
        }, {
            "foo": 134
        }], exceptions.RelationConstraintError,
                              {"constraint": ref.relation_constraints[2]})

        self._test_validation(ref, None, [{
            "foo": 5
        }], exceptions.RelationConstraintError,
                              {"constraint": ref.relation_constraints[3]})
Beispiel #19
0
    def setUp(self):

        TempStorageMixin.setUp(self)

        from cocktail.schema import String, Reference, Collection
        from cocktail.persistence import PersistentObject

        class TestObject(PersistentObject):
            test_field = String(
                unique = True,
                indexed = True
            )
            parent = Reference(bidirectional = True)
            children = Collection(bidirectional = True)

        TestObject.parent.type = TestObject
        TestObject.children.items = Reference(type = TestObject)
        self.test_type = TestObject
Beispiel #20
0
    def test_new_related_end(self):

        from cocktail.schema import SchemaObject, Reference

        class Foo(SchemaObject):
            pass

        backref = Reference()

        class Bar(SchemaObject):
            foo = Reference(type=Foo, related_end=backref)

        self.assertTrue(backref.schema is Foo)
        self.assertTrue(backref.name)
        self.assertTrue(getattr(Foo, backref.name) is backref)
        self.assertTrue(Bar.foo.bidirectional)
        self.assertTrue(backref.bidirectional)
        self.assertTrue(Bar.foo.related_end is backref)
    def test_bidirectional_collection(self):

        from cocktail.schema import Collection, Reference
        from cocktail.persistence import PersistentObject

        class TestObject(PersistentObject):

            parent = Reference(bidirectional=True)

            collection = Collection(cascade_delete=True, bidirectional=True)

        TestObject.parent.type = TestObject
        TestObject.collection.items = Reference(type=TestObject)

        a = TestObject(collection=[TestObject(), TestObject()])
        a.insert()
        a.delete()

        assert not TestObject.index
    def test_bidirectional_default(self):

        from cocktail.schema import Collection, Reference
        from cocktail.persistence import (PersistentObject,
                                          PersistentRelationOrderedSet)

        class Foo(PersistentObject):
            bar = Collection(bidirectional=True)

        class Bar(PersistentObject):
            foo = Reference(bidirectional=True)

        Foo.bar.items = Reference(type=Bar)
        Bar.type = Foo

        foo = Foo()
        self.assertTrue(isinstance(foo.bar, PersistentRelationOrderedSet))
        self.assertTrue(foo.bar.owner is foo)
        self.assertTrue(foo.bar.member is Foo.bar)
Beispiel #23
0
    def test_default(self):

        from cocktail.schema import SchemaObject, Reference, Collection

        class Foo(SchemaObject):
            bars = Collection(bidirectional=True)

        class Bar(SchemaObject):
            foo = Reference(type=Foo, bidirectional=True)

        Foo.bars.items = Reference(type=Bar)
        default_foo = Foo()
        Bar.foo.default = default_foo

        a = Bar()
        b = Bar()

        assert a.foo is default_foo
        assert b.foo is default_foo
        assert len(default_foo.bars) == 2
        assert set(default_foo.bars) == set([a, b])
 class Bar(PersistentObject):
     foo = Reference(bidirectional=True)
Beispiel #25
0
 class Bar(SchemaObject):
     foo = Collection(items=Reference(type=Foo), related_end=backref)
Beispiel #26
0
 def selection(self):
     return self.params.read(
         Collection("selection", items = Reference(type = Item))
     )
Beispiel #27
0
 def root(self):
     return self.params.read(Reference("root", type = Item))
Beispiel #28
0
 class Bar(SchemaObject):
     foo = Reference(type=Foo, bidirectional=True)
Beispiel #29
0
 class Component(SchemaObject):
     container = Reference(type=Container,
                           bidirectional=True,
                           integral=True)
Beispiel #30
0
 def test_default(self):
     from cocktail.schema import Reference
     self.assertFalse(Reference().integral)