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)
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)
class TestObject(PersistentObject): test_field = String( unique = True, indexed = True ) parent = Reference(bidirectional = True) children = Collection(bidirectional = True)
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)
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)
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)
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)
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()
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]
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
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
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]})
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
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)
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)
class Bar(SchemaObject): foo = Collection(items=Reference(type=Foo), related_end=backref)
def selection(self): return self.params.read( Collection("selection", items = Reference(type = Item)) )
def root(self): return self.params.read(Reference("root", type = Item))
class Bar(SchemaObject): foo = Reference(type=Foo, bidirectional=True)
class Component(SchemaObject): container = Reference(type=Container, bidirectional=True, integral=True)
def test_default(self): from cocktail.schema import Reference self.assertFalse(Reference().integral)