def testRecursion(self): # we have to fiddle with PolyConstraint's innards value = schema.ChoiceOf( schema.StringConstraint(), schema.IntegerConstraint(), # will add 'value' here ) self.assertSize(value, 1065) self.assertDepth(value, 1) self.conforms(value, "key") self.conforms(value, 123) self.violates(value, []) mapping = schema.TupleConstraint(schema.StringConstraint(10), value) self.assertSize(mapping, 72 + 75 + 1065) self.assertDepth(mapping, 2) self.conforms(mapping, ("name", "key")) self.conforms(mapping, ("name", 123)) value.alternatives = value.alternatives + (mapping, ) self.assertUnboundedSize(value) self.assertUnboundedDepth(value) self.assertUnboundedSize(mapping) self.assertUnboundedDepth(mapping) # but note that the constraint can still be applied self.conforms(mapping, ("name", 123)) self.conforms(mapping, ("name", "key")) self.conforms(mapping, ("name", ("key", "value"))) self.conforms(mapping, ("name", ("key", 123))) self.violates(mapping, ("name", ("key", []))) l = [] l.append(l) self.violates(mapping, ("name", l))
def testTuple(self): c = schema.TupleConstraint(schema.StringConstraint(10), schema.StringConstraint(100), schema.IntegerConstraint()) self.conforms(c, ("hi", "there buddy, you're number", 1)) self.violates(c, "nope") self.violates(c, ("string", "string", "NaN")) self.violates(c, ("string that is too long", "string", 1)) self.violates(c, ["Are tuples", "and lists the same?", 0]) self.assertSize(c, 72 + 75 + 165 + 73) self.assertDepth(c, 2)
class ReferenceUnslicer(slicer.BaseUnslicer): """I turn an incoming 'my-reference' sequence into a RemoteReference or a RemoteMethodReference.""" state = 0 clid = None interfaceName = None url = None inameConstraint = schema.StringConstraint(200) # TODO: only known RI names? urlConstraint = schema.StringConstraint(200) def checkToken(self, typebyte, size): if self.state == 0: if typebyte not in (tokens.INT, tokens.NEG): raise BananaError("reference ID must be an INT or NEG") elif self.state == 1: self.inameConstraint.checkToken(typebyte, size) elif self.state == 2: self.urlConstraint.checkToken(typebyte, size) else: raise Violation("too many parameters in my-reference") def receiveChild(self, obj, ready_deferred=None): assert not isinstance(obj, defer.Deferred) assert ready_deferred is None if self.state == 0: self.clid = obj self.state = 1 elif self.state == 1: # must be the interface name self.interfaceName = obj if obj == "": self.interfaceName = None self.state = 2 elif self.state == 2: # URL self.url = obj self.state = 3 else: raise BananaError("Too many my-reference parameters") def receiveClose(self): if self.clid is None: raise BananaError("sequence ended too early") tracker = self.broker.getTrackerForYourReference(self.clid, self.interfaceName, self.url) return tracker.getRef(), None def describe(self): if self.clid is None: return "<ref-?>" return "<ref-%s>" % self.clid
def testList(self): l = schema.ListOf(schema.StringConstraint(10)) self.assertSize(l, 71 + 30 * 75) self.assertDepth(l, 2) self.conforms(l, ["one", "two", "three"]) self.violates(l, ("can't", "fool", "me")) self.violates(l, ["but", "perspicacity", "is too long"]) self.conforms(l, ["short", "sweet"]) l2 = schema.ListOf(schema.StringConstraint(10), 3) self.assertSize(l2, 71 + 3 * 75) self.assertDepth(l2, 2) self.conforms(l2, ["the number", "shall be", "three"]) self.violates(l2, ["five", "is", "...", "right", "out"])
def testNestedTuple(self): inner = schema.TupleConstraint(schema.StringConstraint(10), schema.IntegerConstraint()) self.assertSize(inner, 72 + 75 + 73) self.assertDepth(inner, 2) outer = schema.TupleConstraint(schema.StringConstraint(100), inner) self.assertSize(outer, 72 + 165 + 72 + 75 + 73) self.assertDepth(outer, 3) self.conforms(inner, ("hi", 2)) self.conforms(outer, ("long string here", ("short", 3))) self.violates(outer, (("long string here", ("short", 3, "extra")))) self.violates(outer, (("long string here", ("too long string", 3)))) outer2 = schema.TupleConstraint(inner, inner) self.assertSize(outer2, 72 + 2 * (72 + 75 + 73)) self.assertDepth(outer2, 3) self.conforms(outer2, (("hi", 1), ("there", 2))) self.violates(outer2, ("hi", 1, "flat", 2))
def testString(self): c = schema.StringConstraint(10) self.assertSize(c, STR10) self.assertSize(c, STR10) # twice to test seen=[] logic self.assertDepth(c, 1) self.conforms(c, "I'm short") self.violates(c, "I am too long") self.conforms(c, "a" * 10) self.violates(c, "a" * 11) self.violates(c, 123) self.violates(c, Dummy()) self.violates(c, None)
class TheirReferenceUnslicer(slicer.LeafUnslicer): """I accept gifts of third-party references. This is turned into a live reference upon receipt.""" # (their-reference, giftID, URL) state = 0 giftID = None url = None urlConstraint = schema.StringConstraint(200) def checkToken(self, typebyte, size): if self.state == 0: if typebyte != tokens.INT: raise BananaError("their-reference giftID must be an INT") elif self.state == 1: self.urlConstraint.checkToken(typebyte, size) else: raise Violation("too many parameters in their-reference") def receiveChild(self, obj, ready_deferred=None): assert not isinstance(obj, defer.Deferred) assert ready_deferred is None if self.state == 0: self.giftID = obj self.state = 1 elif self.state == 1: # URL self.url = obj self.state = 2 else: raise BananaError("Too many their-reference parameters") def receiveClose(self): if self.giftID is None or self.url is None: raise BananaError("sequence ended too early") d = self.broker.tub.getReference(self.url) d.addBoth(self.ackGift) return d,d def ackGift(self, rref): d = self.broker.remote_broker.callRemote("decgift", giftID=self.giftID, count=1) # if we lose the connection, they'll decref the gift anyway d.addErrback(lambda f: f.trap(ipb.DeadReferenceError)) d.addErrback(lambda f: f.trap(error.ConnectionLost)) d.addErrback(lambda f: f.trap(error.ConnectionDone)) return rref def describe(self): if self.giftID is None: return "<gift-?>" return "<gift-%s>" % self.giftID
def testUnbounded(self): big = schema.StringConstraint(None) self.assertUnboundedSize(big) self.assertDepth(big, 1) self.conforms(big, "blah blah blah blah blah" * 1024) self.violates(big, 123) bag = schema.TupleConstraint(schema.IntegerConstraint(), big) self.assertUnboundedSize(bag) self.assertDepth(bag, 2) polybag = schema.PolyConstraint(schema.IntegerConstraint(), bag) self.assertUnboundedSize(polybag) self.assertDepth(polybag, 2)
def testDict(self): d = schema.DictOf(schema.StringConstraint(10), schema.IntegerConstraint(), maxKeys=4) self.assertDepth(d, 2) self.conforms(d, {"a": 1, "b": 2}) self.conforms(d, {"foo": 123, "bar": 345, "blah": 456, "yar": 789}) self.violates(d, None) self.violates(d, 12) self.violates(d, ["nope"]) self.violates(d, ("nice", "try")) self.violates(d, {1: 2, 3: 4}) self.violates(d, {"a": "b"}) self.violates(d, {"a": 1, "b": 2, "c": 3, "d": 4, "toomuch": 5})
def testPoly(self): c = schema.PolyConstraint(schema.StringConstraint(100), schema.IntegerConstraint()) self.assertSize(c, 165) self.assertDepth(c, 1)