Files
deb-python-colander/colander/tests.py
Chris McDonough 514b06a58c - The concept of "schema binding" was added, which allows for a more
declarative-looking spelling of schemas and schema nodes which have
  dependencies on values available after the schema has already been
  fully constructed.  See the new narrative chapter in the
  documentation entitled "Schema Binding".

- The interface of ``colander.SchemaNode`` has grown a ``__delitem__``
  method.  The ``__iter__``, and ``__getitem__`` methods have now also
  been properly documented.
2010-09-08 20:43:18 +00:00

1772 lines
60 KiB
Python

import unittest
def invalid_exc(func, *arg, **kw):
from colander import Invalid
try:
func(*arg, **kw)
except Invalid, e:
return e
else:
raise AssertionError('Invalid not raised') # pragma: no cover
class TestInvalid(unittest.TestCase):
def _makeOne(self, node, msg=None, val=None):
from colander import Invalid
exc = Invalid(node, msg, val)
return exc
def test_ctor(self):
exc = self._makeOne(None, 'msg', 'val')
self.assertEqual(exc.node, None)
self.assertEqual(exc.msg, 'msg')
self.assertEqual(exc.value, 'val')
self.assertEqual(exc.children, [])
def test_add(self):
exc = self._makeOne(None, 'msg')
other = Dummy()
exc.add(other)
self.failIf(hasattr(other, 'positional'))
self.assertEqual(exc.children, [other])
def test_add_positional(self):
from colander import Positional
p = Positional()
node = DummySchemaNode(p)
exc = self._makeOne(node, 'msg')
other = Dummy()
exc.add(other)
self.assertEqual(other.positional, True)
self.assertEqual(exc.children, [other])
def test__keyname_no_parent(self):
node = DummySchemaNode(None, name='name')
exc = self._makeOne(None, '')
exc.node = node
self.assertEqual(exc._keyname(), 'name')
def test__keyname_positional(self):
exc = self._makeOne(None, '')
exc.positional = True
exc.pos = 2
self.assertEqual(exc._keyname(), '2')
def test__keyname_nonpositional_parent(self):
parent = Dummy()
parent.node = DummySchemaNode(None)
exc = self._makeOne(None, 'me')
exc.parent = parent
exc.pos = 2
exc.node = DummySchemaNode(None, name='name')
self.assertEqual(exc._keyname(), 'name')
def test_paths(self):
exc1 = self._makeOne(None, 'exc1')
exc2 = self._makeOne(None, 'exc2')
exc3 = self._makeOne(None, 'exc3')
exc4 = self._makeOne(None, 'exc4')
exc1.add(exc2)
exc2.add(exc3)
exc1.add(exc4)
paths = list(exc1.paths())
self.assertEqual(paths, [(exc1, exc2, exc3), (exc1, exc4)])
def test_asdict(self):
from colander import Positional
node1 = DummySchemaNode(None, 'node1')
node2 = DummySchemaNode(Positional(), 'node2')
node3 = DummySchemaNode(Positional(), 'node3')
node4 = DummySchemaNode(Positional(), 'node4')
exc1 = self._makeOne(node1, 'exc1')
exc1.pos = 1
exc2 = self._makeOne(node2, 'exc2')
exc3 = self._makeOne(node3, 'exc3')
exc4 = self._makeOne(node4, 'exc4')
exc1.add(exc2, 2)
exc2.add(exc3, 3)
exc1.add(exc4, 4)
d = exc1.asdict()
self.assertEqual(d, {'node1.node2.3': 'exc1; exc2; exc3',
'node1.node4': 'exc1; exc4'})
def test___str__(self):
from colander import Positional
node1 = DummySchemaNode(None, 'node1')
node2 = DummySchemaNode(Positional(), 'node2')
node3 = DummySchemaNode(Positional(), 'node3')
node4 = DummySchemaNode(Positional(), 'node4')
exc1 = self._makeOne(node1, 'exc1')
exc1.pos = 1
exc2 = self._makeOne(node2, 'exc2')
exc3 = self._makeOne(node3, 'exc3')
exc4 = self._makeOne(node4, 'exc4')
exc1.add(exc2, 2)
exc2.add(exc3, 3)
exc1.add(exc4, 4)
result = str(exc1)
self.assertEqual(
result,
"{'node1.node2.3': 'exc1; exc2; exc3', 'node1.node4': 'exc1; exc4'}"
)
def test___setitem__fails(self):
node = DummySchemaNode(None)
exc = self._makeOne(node, 'msg')
self.assertRaises(KeyError, exc.__setitem__, 'notfound', 'msg')
def test___setitem__succeeds(self):
node = DummySchemaNode(None)
child = DummySchemaNode(None)
child.name = 'found'
node.children = [child]
exc = self._makeOne(node, 'msg')
exc['found'] = 'msg2'
self.assertEqual(len(exc.children), 1)
childexc = exc.children[0]
self.assertEqual(childexc.pos, 0)
self.assertEqual(childexc.node.name, 'found')
def test_messages_msg_iterable(self):
node = DummySchemaNode(None)
exc = self._makeOne(node, [123, 456])
self.assertEqual(exc.messages(), [123, 456])
def test_messages_msg_not_iterable(self):
node = DummySchemaNode(None)
exc = self._makeOne(node, 'msg')
self.assertEqual(exc.messages(), ['msg'])
class TestAll(unittest.TestCase):
def _makeOne(self, validators):
from colander import All
return All(*validators)
def test_success(self):
validator1 = DummyValidator()
validator2 = DummyValidator()
validator = self._makeOne([validator1, validator2])
self.assertEqual(validator(None, None), None)
def test_failure(self):
validator1 = DummyValidator('msg1')
validator2 = DummyValidator('msg2')
validator = self._makeOne([validator1, validator2])
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg, ['msg1', 'msg2'])
class TestFunction(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import Function
return Function(*arg, **kw)
def test_success_function_returns_True(self):
validator = self._makeOne(lambda x: True)
self.assertEqual(validator(None, None), None)
def test_fail_function_returns_empty_string(self):
validator = self._makeOne(lambda x: '')
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg, 'Invalid value')
def test_fail_function_returns_False(self):
validator = self._makeOne(lambda x: False)
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg, 'Invalid value')
def test_fail_function_returns_string(self):
validator = self._makeOne(lambda x: 'fail')
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg, 'fail')
def test_propagation(self):
validator = self._makeOne(lambda x: 'a' in x, 'msg')
self.assertRaises(TypeError, validator, None, None)
class TestRange(unittest.TestCase):
def _makeOne(self, **kw):
from colander import Range
return Range(**kw)
def test_success_no_bounds(self):
validator = self._makeOne()
self.assertEqual(validator(None, 1), None)
def test_success_upper_bound_only(self):
validator = self._makeOne(max=1)
self.assertEqual(validator(None, -1), None)
def test_success_minimum_bound_only(self):
validator = self._makeOne(min=0)
self.assertEqual(validator(None, 1), None)
def test_success_min_and_max(self):
validator = self._makeOne(min=1, max=1)
self.assertEqual(validator(None, 1), None)
def test_min_failure(self):
validator = self._makeOne(min=1)
e = invalid_exc(validator, None, 0)
self.assertEqual(e.msg.interpolate(), '0 is less than minimum value 1')
def test_min_failure_msg_override(self):
validator = self._makeOne(min=1, min_err='wrong')
e = invalid_exc(validator, None, 0)
self.assertEqual(e.msg, 'wrong')
def test_max_failure(self):
validator = self._makeOne(max=1)
e = invalid_exc(validator, None, 2)
self.assertEqual(e.msg.interpolate(),
'2 is greater than maximum value 1')
def test_max_failure_msg_override(self):
validator = self._makeOne(max=1, max_err='wrong')
e = invalid_exc(validator, None, 2)
self.assertEqual(e.msg, 'wrong')
class TestRegex(unittest.TestCase):
def _makeOne(self, pattern):
from colander import Regex
return Regex(pattern)
def test_valid_regex(self):
self.assertEqual(self._makeOne('a')(None, 'a'), None)
self.assertEqual(self._makeOne('[0-9]+')(None, '1111'), None)
self.assertEqual(self._makeOne('')(None, ''), None)
self.assertEqual(self._makeOne('.*')(None, ''), None)
def test_invalid_regexs(self):
from colander import Invalid
self.assertRaises(Invalid, self._makeOne('[0-9]+'), None, 'a')
self.assertRaises(Invalid, self._makeOne('a{2,4}'), None, 'ba')
def test_regex_not_string(self):
from colander import Invalid
import re
regex = re.compile('[0-9]+')
self.assertEqual(self._makeOne(regex)(None, '01'), None)
self.assertRaises(Invalid, self._makeOne(regex), None, 't')
class TestEmail(unittest.TestCase):
def _makeOne(self):
from colander import Email
return Email()
def test_valid_emails(self):
validator = self._makeOne()
self.assertEqual(validator(None, 'me@here.com'), None)
self.assertEqual(validator(None, 'me1@here1.com'), None)
self.assertEqual(validator(None, 'name@here1.us'), None)
self.assertEqual(validator(None, 'name@here1.info'), None)
self.assertEqual(validator(None, 'foo@bar.baz.biz'), None)
def test_empty_email(self):
validator = self._makeOne()
e = invalid_exc(validator, None, '')
self.assertEqual(e.msg, 'Invalid email address')
def test_invalid_emails(self):
validator = self._makeOne()
from colander import Invalid
self.assertRaises(Invalid, validator, None, 'me@here.')
self.assertRaises(Invalid, validator, None, 'name@here.comcom')
self.assertRaises(Invalid, validator, None, '@here.us')
self.assertRaises(Invalid, validator, None, '(name)@here.info')
class TestLength(unittest.TestCase):
def _makeOne(self, min=None, max=None):
from colander import Length
return Length(min=min, max=max)
def test_success_no_bounds(self):
validator = self._makeOne()
self.assertEqual(validator(None, ''), None)
def test_success_upper_bound_only(self):
validator = self._makeOne(max=1)
self.assertEqual(validator(None, 'a'), None)
def test_success_minimum_bound_only(self):
validator = self._makeOne(min=0)
self.assertEqual(validator(None, ''), None)
def test_success_min_and_max(self):
validator = self._makeOne(min=1, max=1)
self.assertEqual(validator(None, 'a'), None)
def test_min_failure(self):
validator = self._makeOne(min=1)
e = invalid_exc(validator, None, '')
self.assertEqual(e.msg.interpolate(), 'Shorter than minimum length 1')
def test_max_failure(self):
validator = self._makeOne(max=1)
e = invalid_exc(validator, None, 'ab')
self.assertEqual(e.msg.interpolate(), 'Longer than maximum length 1')
class TestOneOf(unittest.TestCase):
def _makeOne(self, values):
from colander import OneOf
return OneOf(values)
def test_success(self):
validator = self._makeOne([1])
self.assertEqual(validator(None, 1), None)
def test_failure(self):
validator = self._makeOne([1, 2])
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg.interpolate(), '"None" is not one of 1, 2')
class TestMapping(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import Mapping
return Mapping(*arg, **kw)
def test_ctor_bad_unknown(self):
self.assertRaises(ValueError, self._makeOne, 'badarg')
def test_ctor_good_unknown(self):
try:
self._makeOne('ignore')
self._makeOne('raise')
self._makeOne('preserve')
except ValueError, e: # pragma: no cover
raise AssertionError(e)
def test_deserialize_not_a_mapping(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, None)
self.failUnless(
e.msg.interpolate().startswith('"None" is not a mapping type'))
def test_deserialize_no_subnodes(self):
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, {})
self.assertEqual(result, {})
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.deserialize(node, {'a':1})
self.assertEqual(result, {'a':1})
def test_deserialize_unknown_raise(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne(unknown='raise')
e = invalid_exc(typ.deserialize, node, {'a':1, 'b':2})
self.assertEqual(e.msg.interpolate(),
"Unrecognized keys in mapping: \"{'b': 2}\"")
def test_deserialize_unknown_preserve(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne(unknown='preserve')
result = typ.deserialize(node, {'a':1, 'b':2})
self.assertEqual(result, {'a':1, 'b':2})
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, {'a':1, 'b':2})
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
def test_deserialize_subnode_missing_default(self):
import colander
node = DummySchemaNode(None)
node.children = [
DummySchemaNode(None, name='a'),
DummySchemaNode(None, name='b', default='abc'),
]
typ = self._makeOne()
result = typ.deserialize(node, {'a':1})
self.assertEqual(result, {'a':1, 'b':colander.null})
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, {})
def test_serialize_not_a_mapping(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, None)
self.failUnless(
e.msg.interpolate().startswith('"None" is not a mapping type'))
def test_serialize_no_subnodes(self):
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, {})
self.assertEqual(result, {})
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, {'a':1})
self.assertEqual(result, {'a':1})
def test_serialize_with_unknown(self):
node = DummySchemaNode(None)
node.children = [
DummySchemaNode(None, name='a'),
]
typ = self._makeOne()
result = typ.serialize(node, {'a':1, 'b':2})
self.assertEqual(result, {'a':1})
def test_serialize_value_is_null(self):
node = DummySchemaNode(None)
from colander import null
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, null)
self.assertEqual(result, {'a':null})
class TestTuple(unittest.TestCase):
def _makeOne(self):
from colander import Tuple
return Tuple()
def test_deserialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, None)
self.assertEqual(
e.msg.interpolate(),
'"None" is not iterable')
self.assertEqual(e.node, node)
def test_deserialize_no_subnodes(self):
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, ())
self.assertEqual(result, ())
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.deserialize(node, ('a',))
self.assertEqual(result, ('a',))
def test_deserialize_toobig(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, ('a','b'))
self.assertEqual(e.msg.interpolate(),
"\"('a', 'b')\" has an incorrect number of elements (expected 1, was 2)")
def test_deserialize_toosmall(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, ())
self.assertEqual(e.msg.interpolate(),
'"()" has an incorrect number of elements (expected 1, was 0)')
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
def test_serialize_null(self):
import colander
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, colander.null)
self.assertEqual(result, colander.null)
def test_serialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, None)
self.assertEqual(
e.msg.interpolate(),
'"None" is not iterable')
self.assertEqual(e.node, node)
def test_serialize_no_subnodes(self):
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, ())
self.assertEqual(result, ())
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, ('a',))
self.assertEqual(result, ('a',))
def test_serialize_toobig(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, ('a','b'))
self.assertEqual(e.msg.interpolate(),
"\"('a', 'b')\" has an incorrect number of elements (expected 1, was 2)")
def test_serialize_toosmall(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, ())
self.assertEqual(e.msg.interpolate(),
'"()" has an incorrect number of elements (expected 1, was 0)'
)
def test_serialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
class TestSequence(unittest.TestCase):
def _makeOne(self, **kw):
from colander import Sequence
return Sequence(**kw)
def test_alias(self):
from colander import Seq
from colander import Sequence
self.assertEqual(Seq, Sequence)
def test_deserialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
node.children = [node]
e = invalid_exc(typ.deserialize, node, None)
self.assertEqual(
e.msg.interpolate(),
'"None" is not iterable')
self.assertEqual(e.node, node)
def test_deserialize_not_iterable_accept_scalar(self):
node = DummySchemaNode(None)
typ = self._makeOne(accept_scalar=True)
node.children = [node]
result = typ.deserialize(node, None)
self.assertEqual(result, [None])
def test_deserialize_no_subnodes(self):
typ = self._makeOne()
node = DummySchemaNode(None)
node.children = [node]
result = typ.deserialize(node, ())
self.assertEqual(result, [])
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
node.children = [node]
result = typ.deserialize(node, ('a',))
self.assertEqual(result, ['a'])
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None, exc='Wrong')
typ = self._makeOne()
node.children = [node]
e = invalid_exc(typ.deserialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
def test_serialize_null(self):
import colander
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, colander.null)
self.assertEqual(result, colander.null)
def test_serialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
node.children = [node]
e = invalid_exc(typ.serialize, node, None)
self.assertEqual(
e.msg.interpolate(),
'"None" is not iterable')
self.assertEqual(e.node, node)
def test_serialize_not_iterable_accept_scalar(self):
node = DummySchemaNode(None)
typ = self._makeOne(accept_scalar=True)
node.children = [node]
result = typ.serialize(node, None)
self.assertEqual(result, [None])
def test_serialize_no_subnodes(self):
node = DummySchemaNode(None)
node.children = [node]
typ = self._makeOne()
result = typ.serialize(node, ())
self.assertEqual(result, [])
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, ('a',))
self.assertEqual(result, ['a'])
def test_serialize_subnodes_raise(self):
node = DummySchemaNode(None, exc='Wrong')
typ = self._makeOne()
node.children = [node]
e = invalid_exc(typ.serialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
class TestString(unittest.TestCase):
def _makeOne(self, encoding=None):
from colander import String
return String(encoding)
def test_alias(self):
from colander import Str
from colander import String
self.assertEqual(Str, String)
def test_deserialize_emptystring(self):
node = DummySchemaNode(None)
typ = self._makeOne(None)
result = typ.deserialize(node, '')
self.assertEqual(result, '')
def test_deserialize_uncooperative(self):
val = Uncooperative()
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.failUnless(e.msg)
def test_deserialize_unicode_from_None(self):
uni = u'\xf8'
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, uni)
self.assertEqual(result, uni)
def test_deserialize_nonunicode_from_None(self):
value = object()
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, value)
self.assertEqual(result, unicode(value))
def test_deserialize_from_utf8(self):
utf8 = '\xc3\xb8'
uni = u'\xf8'
node = DummySchemaNode(None)
typ = self._makeOne('utf-8')
result = typ.deserialize(node, utf8)
self.assertEqual(result, uni)
def test_deserialize_from_utf16(self):
utf16 = '\xff\xfe\xf8\x00'
uni = u'\xf8'
node = DummySchemaNode(None)
typ = self._makeOne('utf-16')
result = typ.deserialize(node, utf16)
self.assertEqual(result, uni)
def test_serialize_null(self):
from colander import null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, null)
self.assertEqual(result, null)
def test_serialize_uncooperative(self):
val = Uncooperative()
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, val)
self.failUnless(e.msg)
def test_serialize_nonunicode_to_None(self):
value = object()
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, value)
self.assertEqual(result, unicode(value))
def test_serialize_unicode_to_None(self):
value = u'abc'
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, value)
self.assertEqual(result, value)
def test_serialize_to_utf8(self):
utf8 = '\xc3\xb8'
uni = u'\xf8'
node = DummySchemaNode(None)
typ = self._makeOne('utf-8')
result = typ.serialize(node, uni)
self.assertEqual(result, utf8)
def test_serialize_to_utf16(self):
utf16 = '\xff\xfe\xf8\x00'
uni = u'\xf8'
node = DummySchemaNode(None)
typ = self._makeOne('utf-16')
result = typ.serialize(node, uni)
self.assertEqual(result, utf16)
def test_serialize_string_with_high_unresolveable_high_order_chars(self):
not_utf8 = '\xff\xfe\xf8\x00'
node = DummySchemaNode(None)
typ = self._makeOne('utf-8')
e = invalid_exc(typ.serialize, node, not_utf8)
self.failUnless('cannot be serialized' in e.msg)
class TestInteger(unittest.TestCase):
def _makeOne(self):
from colander import Integer
return Integer()
def test_alias(self):
from colander import Int
from colander import Integer
self.assertEqual(Int, Integer)
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_emptystring_required(self):
val = ''
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.assertEqual(e.msg, 'Required')
def test_deserialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.failUnless(e.msg)
def test_deserialize_ok(self):
val = '1'
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, val)
self.assertEqual(result, 1)
def test_serialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, val)
self.failUnless(e.msg)
def test_serialize_ok(self):
val = 1
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, '1')
class TestFloat(unittest.TestCase):
def _makeOne(self):
from colander import Float
return Float()
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_emptystring_required(self):
val = ''
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.assertEqual(e.msg, 'Required')
def test_deserialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.failUnless(e.msg)
def test_deserialize_ok(self):
val = '1.0'
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, val)
self.assertEqual(result, 1.0)
def test_serialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, val)
self.failUnless(e.msg)
def test_serialize_ok(self):
val = 1.0
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, '1.0')
class TestDecimal(unittest.TestCase):
def _makeOne(self):
from colander import Decimal
return Decimal()
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_emptystring_required(self):
val = ''
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.assertEqual(e.msg, 'Required')
def test_deserialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, val)
self.failUnless(e.msg)
def test_deserialize_ok(self):
import decimal
val = '1.0'
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.deserialize(node, val)
self.assertEqual(result, decimal.Decimal('1.0'))
def test_serialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, val)
self.failUnless(e.msg)
def test_serialize_ok(self):
val = 1.0
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, '1.0')
class TestBoolean(unittest.TestCase):
def _makeOne(self):
from colander import Boolean
return Boolean()
def test_alias(self):
from colander import Bool
from colander import Boolean
self.assertEqual(Bool, Boolean)
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_deserialize(self):
typ = self._makeOne()
node = DummySchemaNode(None)
self.assertEqual(typ.deserialize(node, 'false'), False)
self.assertEqual(typ.deserialize(node, 'FALSE'), False)
self.assertEqual(typ.deserialize(node, '0'), False)
self.assertEqual(typ.deserialize(node, 'true'), True)
self.assertEqual(typ.deserialize(node, 'other'), True)
def test_deserialize_unstringable(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.deserialize, node, Uncooperative())
self.failUnless(e.msg.endswith('not a string'))
def test_serialize(self):
typ = self._makeOne()
node = DummySchemaNode(None)
self.assertEqual(typ.serialize(node, 1), 'true')
self.assertEqual(typ.serialize(node, True), 'true')
self.assertEqual(typ.serialize(node, None), 'false')
self.assertEqual(typ.serialize(node, False), 'false')
class TestGlobalObject(unittest.TestCase):
def _makeOne(self, package=None):
from colander import GlobalObject
return GlobalObject(package)
def test_zope_dottedname_style_resolve_absolute(self):
typ = self._makeOne()
result = typ._zope_dottedname_style(None,
'colander.tests.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_zope_dottedname_style_irrresolveable_absolute(self):
typ = self._makeOne()
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
'colander.tests.nonexisting')
def test__zope_dottedname_style_resolve_relative(self):
import colander
typ = self._makeOne(package=colander)
node = DummySchemaNode(None)
result = typ._zope_dottedname_style(node, '.tests.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__zope_dottedname_style_resolve_relative_leading_dots(self):
import colander
typ = self._makeOne(package=colander.tests)
node = DummySchemaNode(None)
result = typ._zope_dottedname_style(node, '..tests.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__zope_dottedname_style_resolve_relative_is_dot(self):
import colander.tests
typ = self._makeOne(package=colander.tests)
result = typ._zope_dottedname_style(None, '.')
self.assertEqual(result, colander.tests)
def test__zope_dottedname_style_irresolveable_relative_is_dot(self):
typ = self._makeOne()
e = invalid_exc(typ._zope_dottedname_style, None, '.')
self.assertEqual(
e.msg.interpolate(),
'relative name "." irresolveable without package')
def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self):
typ = self._makeOne()
e = invalid_exc(typ._zope_dottedname_style, None, '.whatever')
self.assertEqual(
e.msg.interpolate(),
'relative name ".whatever" irresolveable without package')
def test_zope_dottedname_style_irrresolveable_relative(self):
import colander.tests
typ = self._makeOne(package=colander)
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
'.notexisting')
def test__zope_dottedname_style_resolveable_relative(self):
import colander
typ = self._makeOne(package=colander)
result = typ._zope_dottedname_style(None, '.tests')
from colander import tests
self.assertEqual(result, tests)
def test__zope_dottedname_style_irresolveable_absolute(self):
typ = self._makeOne()
self.assertRaises(ImportError,
typ._zope_dottedname_style, None, 'colander.fudge.bar')
def test__zope_dottedname_style_resolveable_absolute(self):
typ = self._makeOne()
result = typ._zope_dottedname_style(None,
'colander.tests.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_resolve_absolute(self):
typ = self._makeOne()
result = typ._pkg_resources_style(None,
'colander.tests:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_irrresolveable_absolute(self):
typ = self._makeOne()
self.assertRaises(ImportError, typ._pkg_resources_style, None,
'colander.tests:nonexisting')
def test__pkg_resources_style_resolve_relative_startswith_colon(self):
import colander.tests
typ = self._makeOne(package=colander.tests)
result = typ._pkg_resources_style(None, ':TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_resolve_relative_startswith_dot(self):
import colander
typ = self._makeOne(package=colander)
result = typ._pkg_resources_style(None, '.tests:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test__pkg_resources_style_resolve_relative_is_dot(self):
import colander.tests
typ = self._makeOne(package=colander.tests)
result = typ._pkg_resources_style(None, '.')
self.assertEqual(result, colander.tests)
def test__pkg_resources_style_resolve_relative_nocurrentpackage(self):
typ = self._makeOne()
import colander
self.assertRaises(colander.Invalid, typ._pkg_resources_style, None,
'.whatever')
def test__pkg_resources_style_irrresolveable_relative(self):
import colander.tests
typ = self._makeOne(package=colander)
self.assertRaises(ImportError, typ._pkg_resources_style, None,
':notexisting')
def test_deserialize_not_a_string(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.deserialize, node, None)
self.assertEqual(e.msg.interpolate(), '"None" is not a string')
def test_deserialize_using_pkgresources_style(self):
typ = self._makeOne()
node = DummySchemaNode(None)
result = typ.deserialize(node, 'colander.tests:TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_deserialize_using_zope_dottedname_style(self):
typ = self._makeOne()
node = DummySchemaNode(None)
result = typ.deserialize(node, 'colander.tests.TestGlobalObject')
self.assertEqual(result, self.__class__)
def test_deserialize_style_raises(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.deserialize, node, 'cant.be.found')
self.assertEqual(e.msg.interpolate(),
'The dotted name "cant.be.found" cannot be imported')
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_ok(self):
import colander.tests
typ = self._makeOne()
node = DummySchemaNode(None)
result = typ.serialize(node, colander.tests)
self.assertEqual(result, 'colander.tests')
def test_serialize_fail(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.serialize, node, None)
self.assertEqual(e.msg.interpolate(), '"None" has no __name__')
class TestDateTime(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import DateTime
return DateTime(*arg, **kw)
def _dt(self):
import datetime
return datetime.datetime(2010, 4, 26, 10, 48)
def _today(self):
import datetime
return datetime.date.today()
def test_ctor_default_tzinfo_None(self):
import iso8601
typ = self._makeOne()
self.assertEqual(typ.default_tzinfo.__class__, iso8601.iso8601.Utc)
def test_ctor_default_tzinfo_non_None(self):
import iso8601
tzinfo = iso8601.iso8601.FixedOffset(1, 0, 'myname')
typ = self._makeOne(default_tzinfo=tzinfo)
self.assertEqual(typ.default_tzinfo, tzinfo)
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_with_garbage(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.serialize, node, 'garbage')
self.assertEqual(e.msg.interpolate(),
'"garbage" is not a datetime object')
def test_serialize_with_date(self):
import datetime
typ = self._makeOne()
date = self._today()
node = DummySchemaNode(None)
result = typ.serialize(node, date)
expected = datetime.datetime.combine(date, datetime.time())
expected = expected.replace(tzinfo=typ.default_tzinfo).isoformat()
self.assertEqual(result, expected)
def test_serialize_with_naive_datetime(self):
typ = self._makeOne()
node = DummySchemaNode(None)
dt = self._dt()
result = typ.serialize(node, dt)
expected = dt.replace(tzinfo=typ.default_tzinfo).isoformat()
self.assertEqual(result, expected)
def test_serialize_with_tzware_datetime(self):
import iso8601
typ = self._makeOne()
dt = self._dt()
tzinfo = iso8601.iso8601.FixedOffset(1, 0, 'myname')
dt = dt.replace(tzinfo=tzinfo)
node = DummySchemaNode(None)
result = typ.serialize(node, dt)
expected = dt.isoformat()
self.assertEqual(result, expected)
def test_deserialize_date(self):
import datetime
import iso8601
date = self._today()
typ = self._makeOne()
formatted = date.isoformat()
node = DummySchemaNode(None)
result = typ.deserialize(node, formatted)
expected = datetime.datetime.combine(result, datetime.time())
tzinfo = iso8601.iso8601.Utc()
expected = expected.replace(tzinfo=tzinfo)
self.assertEqual(result.isoformat(), expected.isoformat())
def test_deserialize_invalid_ParseError(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, 'garbage')
self.failUnless('Invalid' in e.msg)
def test_deserialize_success(self):
import iso8601
typ = self._makeOne()
dt = self._dt()
tzinfo = iso8601.iso8601.FixedOffset(1, 0, 'myname')
dt = dt.replace(tzinfo=tzinfo)
iso = dt.isoformat()
node = DummySchemaNode(None)
result = typ.deserialize(node, iso)
self.assertEqual(result.isoformat(), iso)
class TestDate(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import Date
return Date(*arg, **kw)
def _dt(self):
import datetime
return datetime.datetime(2010, 4, 26, 10, 48)
def _today(self):
import datetime
return datetime.date.today()
def test_serialize_null(self):
import colander
val = colander.null
node = DummySchemaNode(None)
typ = self._makeOne()
result = typ.serialize(node, val)
self.assertEqual(result, colander.null)
def test_serialize_with_garbage(self):
typ = self._makeOne()
node = DummySchemaNode(None)
e = invalid_exc(typ.serialize, node, 'garbage')
self.assertEqual(e.msg.interpolate(), '"garbage" is not a date object')
def test_serialize_with_date(self):
typ = self._makeOne()
date = self._today()
node = DummySchemaNode(None)
result = typ.serialize(node, date)
expected = date.isoformat()
self.assertEqual(result, expected)
def test_serialize_with_datetime(self):
typ = self._makeOne()
dt = self._dt()
node = DummySchemaNode(None)
result = typ.serialize(node, dt)
expected = dt.date().isoformat()
self.assertEqual(result, expected)
def test_deserialize_invalid_ParseError(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, 'garbage')
self.failUnless('Invalid' in e.msg)
def test_deserialize_invalid_weird(self):
node = DummySchemaNode(None)
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, '10-10-10-10')
self.failUnless('Invalid' in e.msg)
def test_deserialize_success_date(self):
typ = self._makeOne()
date = self._today()
iso = date.isoformat()
node = DummySchemaNode(None)
result = typ.deserialize(node, iso)
self.assertEqual(result.isoformat(), iso)
def test_deserialize_success_datetime(self):
dt = self._dt()
typ = self._makeOne()
iso = dt.isoformat()
node = DummySchemaNode(None)
result = typ.deserialize(node, iso)
self.assertEqual(result.isoformat(), dt.date().isoformat())
class TestSchemaNode(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import SchemaNode
return SchemaNode(*arg, **kw)
def test_new_sets_order(self):
node = self._makeOne(None)
self.failUnless(hasattr(node, '_order'))
def test_ctor_no_title(self):
node = self._makeOne(None, 0, validator=1, default=2, name='name_a',
missing='missing')
self.assertEqual(node.typ, None)
self.assertEqual(node.children, [0])
self.assertEqual(node.validator, 1)
self.assertEqual(node.default, 2)
self.assertEqual(node.missing, 'missing')
self.assertEqual(node.name, 'name_a')
self.assertEqual(node.title, 'Name A')
def test_ctor_with_title(self):
node = self._makeOne(None, 0, validator=1, default=2, name='name',
title='title')
self.assertEqual(node.typ, None)
self.assertEqual(node.children, [0])
self.assertEqual(node.validator, 1)
self.assertEqual(node.default, 2)
self.assertEqual(node.name, 'name')
self.assertEqual(node.title, 'title')
def test_ctor_with_description(self):
node = self._makeOne(None, 0, validator=1, default=2, name='name',
title='title', description='desc')
self.assertEqual(node.description, 'desc')
def test_ctor_with_widget(self):
node = self._makeOne(None, 0, widget='abc')
self.assertEqual(node.widget, 'abc')
def test_ctor_with_bad_kwargs(self):
self.assertRaises(TypeError, self._makeOne, None, 0, foo=1)
def test_required_true(self):
node = self._makeOne(None)
self.assertEqual(node.required, True)
def test_required_false(self):
node = self._makeOne(None, missing=1)
self.assertEqual(node.required, False)
def test_deserialize_no_validator(self):
typ = DummyType()
node = self._makeOne(typ)
result = node.deserialize(1)
self.assertEqual(result, 1)
def test_deserialize_with_validator(self):
typ = DummyType()
validator = DummyValidator(msg='Wrong')
node = self._makeOne(typ, validator=validator)
e = invalid_exc(node.deserialize, 1)
self.assertEqual(e.msg, 'Wrong')
def test_deserialize_value_is_null_no_missing(self):
from colander import null
from colander import Invalid
typ = DummyType()
node = self._makeOne(typ)
self.assertRaises(Invalid, node.deserialize, null)
def test_deserialize_value_is_null_with_missing(self):
from colander import null
typ = DummyType()
node = self._makeOne(typ)
node.missing = 'abc'
self.assertEqual(node.deserialize(null), 'abc')
def test_deserialize_noargs_uses_default(self):
typ = DummyType()
node = self._makeOne(typ)
node.missing = 'abc'
self.assertEqual(node.deserialize(), 'abc')
def test_deserialize_null_can_be_used_as_missing(self):
from colander import null
typ = DummyType()
node = self._makeOne(typ)
node.missing = null
self.assertEqual(node.deserialize(null), null)
def test_serialize(self):
typ = DummyType()
node = self._makeOne(typ)
result = node.serialize(1)
self.assertEqual(result, 1)
def test_serialize_value_is_null_no_default(self):
from colander import null
typ = DummyType()
node = self._makeOne(typ)
result = node.serialize(null)
self.assertEqual(result, null)
def test_serialize_value_is_null_with_default(self):
from colander import null
typ = DummyType()
node = self._makeOne(typ)
node.default = 1
result = node.serialize(null)
self.assertEqual(result, 1)
def test_serialize_noargs_uses_default(self):
typ = DummyType()
node = self._makeOne(typ)
node.default = 'abc'
self.assertEqual(node.serialize(), 'abc')
def test_add(self):
node = self._makeOne(None)
node.add(1)
self.assertEqual(node.children, [1])
def test_repr(self):
node = self._makeOne(None, name='flub')
result = repr(node)
self.failUnless(result.startswith('<colander.SchemaNode object at '))
self.failUnless(result.endswith("(named flub)>"))
def test___getitem__success(self):
node = self._makeOne(None)
another = self._makeOne(None, name='another')
node.add(another)
self.assertEqual(node['another'], another)
def test___getitem__failure(self):
node = self._makeOne(None)
self.assertRaises(KeyError, node.__getitem__, 'another')
def test___delitem__success(self):
node = self._makeOne(None)
another = self._makeOne(None, name='another')
node.add(another)
del node['another']
self.assertEqual(node.children, [])
def test___delitem__failure(self):
node = self._makeOne(None)
self.assertRaises(KeyError, node.__delitem__, 'another')
def test___iter__(self):
node = self._makeOne(None)
node.children = ['a', 'b', 'c']
it = node.__iter__()
self.assertEqual(list(it), ['a', 'b', 'c'])
def test_clone(self):
inner_typ = DummyType()
outer_typ = DummyType()
outer_node = self._makeOne(outer_typ, name='outer')
inner_node = self._makeOne(inner_typ, name='inner')
outer_node.foo = 1
inner_node.foo = 2
outer_node.children = [inner_node]
outer_clone = outer_node.clone()
self.failIf(outer_clone is outer_node)
self.assertEqual(outer_clone.typ, outer_typ)
self.assertEqual(outer_clone.name, 'outer')
self.assertEqual(outer_node.foo, 1)
self.assertEqual(len(outer_clone.children), 1)
inner_clone = outer_clone.children[0]
self.failIf(inner_clone is inner_node)
self.assertEqual(inner_clone.typ, inner_typ)
self.assertEqual(inner_clone.name, 'inner')
self.assertEqual(inner_clone.foo, 2)
def test_bind(self):
from colander import deferred
inner_typ = DummyType()
outer_typ = DummyType()
def dv(node, kw):
self.failUnless(node.name in ['outer', 'inner'])
self.failUnless('a' in kw)
return '123'
dv = deferred(dv)
outer_node = self._makeOne(outer_typ, name='outer', missing=dv)
inner_node = self._makeOne(inner_typ, name='inner', validator=dv,
missing=dv)
outer_node.children = [inner_node]
outer_clone = outer_node.bind(a=1)
self.failIf(outer_clone is outer_node)
self.assertEqual(outer_clone.missing, '123')
inner_clone = outer_clone.children[0]
self.failIf(inner_clone is inner_node)
self.assertEqual(inner_clone.missing, '123')
self.assertEqual(inner_clone.validator, '123')
def test_bind_with_after_bind(self):
from colander import deferred
inner_typ = DummyType()
outer_typ = DummyType()
def dv(node, kw):
self.failUnless(node.name in ['outer', 'inner'])
self.failUnless('a' in kw)
return '123'
dv = deferred(dv)
def remove_inner(node, kw):
self.assertEqual(kw, {'a':1})
del node['inner']
outer_node = self._makeOne(outer_typ, name='outer', missing=dv,
after_bind=remove_inner)
inner_node = self._makeOne(inner_typ, name='inner', validator=dv,
missing=dv)
outer_node.children = [inner_node]
outer_clone = outer_node.bind(a=1)
self.failIf(outer_clone is outer_node)
self.assertEqual(outer_clone.missing, '123')
self.assertEqual(len(outer_clone.children), 0)
self.assertEqual(len(outer_node.children), 1)
class TestDeferred(unittest.TestCase):
def _makeOne(self, wrapped):
from colander import deferred
return deferred(wrapped)
def test_ctor(self):
wrapped = '123'
inst = self._makeOne(wrapped)
self.assertEqual(inst.wrapped, wrapped)
def test___call__(self):
n = object()
k = object()
def wrapped(node, kw):
self.assertEqual(node, n)
self.assertEqual(kw, k)
return 'abc'
inst = self._makeOne(wrapped)
result= inst(n, k)
self.assertEqual(result, 'abc')
class TestSchema(unittest.TestCase):
def test_alias(self):
from colander import Schema
from colander import MappingSchema
self.assertEqual(Schema, MappingSchema)
def test_it(self):
import colander
class MySchema(colander.Schema):
thing_a = colander.SchemaNode(colander.String())
thing2 = colander.SchemaNode(colander.String(), title='bar')
node = MySchema(default='abc')
self.failUnless(hasattr(node, '_order'))
self.assertEqual(node.default, 'abc')
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Mapping)
self.assertEqual(node.children[0].typ.__class__, colander.String)
self.assertEqual(node.children[0].title, 'Thing A')
self.assertEqual(node.children[1].title, 'bar')
class TestSequenceSchema(unittest.TestCase):
def test_succeed(self):
import colander
_inner = colander.SchemaNode(colander.String())
class MySchema(colander.SequenceSchema):
inner = _inner
node = MySchema()
self.failUnless(hasattr(node, '_order'))
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Sequence)
self.assertEqual(node.children[0], _inner)
def test_fail_toomany(self):
import colander
thingnode = colander.SchemaNode(colander.String())
thingnode2 = colander.SchemaNode(colander.String())
class MySchema(colander.SequenceSchema):
thing = thingnode
thing2 = thingnode2
e = invalid_exc(MySchema)
self.assertEqual(
e.msg,
'Sequence schemas must have exactly one child node')
def test_fail_toofew(self):
import colander
class MySchema(colander.SequenceSchema):
pass
e = invalid_exc(MySchema)
self.assertEqual(
e.msg,
'Sequence schemas must have exactly one child node')
class TestTupleSchema(unittest.TestCase):
def test_it(self):
import colander
class MySchema(colander.TupleSchema):
thing = colander.SchemaNode(colander.String())
node = MySchema()
self.failUnless(hasattr(node, '_order'))
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Tuple)
self.assertEqual(node.children[0].typ.__class__, colander.String)
class TestFunctional(object):
def test_deserialize_ok(self):
import colander.tests
data = {
'int':'10',
'ob':'colander.tests',
'seq':[('1', 's'),('2', 's'), ('3', 's'), ('4', 's')],
'seq2':[{'key':'1', 'key2':'2'}, {'key':'3', 'key2':'4'}],
'tup':('1', 's'),
}
schema = self._makeSchema()
result = schema.deserialize(data)
self.assertEqual(result['int'], 10)
self.assertEqual(result['ob'], colander.tests)
self.assertEqual(result['seq'],
[(1, 's'), (2, 's'), (3, 's'), (4, 's')])
self.assertEqual(result['seq2'],
[{'key':1, 'key2':2}, {'key':3, 'key2':4}])
self.assertEqual(result['tup'], (1, 's'))
def test_invalid_asdict(self):
expected = {
'int': '20 is greater than maximum value 10',
'ob': 'The dotted name "no.way.this.exists" cannot be imported',
'seq.0.0': '"q" is not a number',
'seq.1.0': '"w" is not a number',
'seq.2.0': '"e" is not a number',
'seq.3.0': '"r" is not a number',
'seq2.0.key': '"t" is not a number',
'seq2.0.key2': '"y" is not a number',
'seq2.1.key': '"u" is not a number',
'seq2.1.key2': '"i" is not a number',
'tup.0': '"s" is not a number'}
data = {
'int':'20',
'ob':'no.way.this.exists',
'seq':[('q', 's'),('w', 's'), ('e', 's'), ('r', 's')],
'seq2':[{'key':'t', 'key2':'y'}, {'key':'u', 'key2':'i'}],
'tup':('s', 's'),
}
schema = self._makeSchema()
e = invalid_exc(schema.deserialize, data)
errors = e.asdict()
self.assertEqual(errors, expected)
class TestImperative(unittest.TestCase, TestFunctional):
def _makeSchema(self):
import colander
integer = colander.SchemaNode(
colander.Integer(),
name='int',
validator=colander.Range(0, 10)
)
ob = colander.SchemaNode(
colander.GlobalObject(package=colander),
name='ob',
)
tup = colander.SchemaNode(
colander.Tuple(),
colander.SchemaNode(
colander.Integer(),
name='tupint',
),
colander.SchemaNode(
colander.String(),
name='tupstring',
),
name='tup',
)
seq = colander.SchemaNode(
colander.Sequence(),
tup,
name='seq',
)
seq2 = colander.SchemaNode(
colander.Sequence(),
colander.SchemaNode(
colander.Mapping(),
colander.SchemaNode(
colander.Integer(),
name='key',
),
colander.SchemaNode(
colander.Integer(),
name='key2',
),
name='mapping',
),
name='seq2',
)
schema = colander.SchemaNode(
colander.Mapping(),
integer,
ob,
tup,
seq,
seq2)
return schema
class TestDeclarative(unittest.TestCase, TestFunctional):
def _makeSchema(self):
import colander
class TupleSchema(colander.TupleSchema):
tupint = colander.SchemaNode(colander.Int())
tupstring = colander.SchemaNode(colander.String())
class MappingSchema(colander.MappingSchema):
key = colander.SchemaNode(colander.Int())
key2 = colander.SchemaNode(colander.Int())
class SequenceOne(colander.SequenceSchema):
tuple = TupleSchema()
class SequenceTwo(colander.SequenceSchema):
mapping = MappingSchema()
class MainSchema(colander.MappingSchema):
int = colander.SchemaNode(colander.Int(),
validator=colander.Range(0, 10))
ob = colander.SchemaNode(colander.GlobalObject(package=colander))
seq = SequenceOne()
tup = TupleSchema()
seq2 = SequenceTwo()
schema = MainSchema()
return schema
class Test_null(unittest.TestCase):
def test___nonzero__(self):
from colander import null
self.failIf(null)
def test___repr__(self):
from colander import null
self.assertEqual(repr(null), '<colander.null>')
class Dummy(object):
pass
class DummySchemaNode(object):
def __init__(self, typ, name='', exc=None, default=None):
self.typ = typ
self.name = name
self.exc = exc
self.required = default is None
self.default = default
self.children = []
def deserialize(self, val):
from colander import Invalid
if self.exc:
raise Invalid(self, self.exc)
return val
def serialize(self, val):
from colander import Invalid
if self.exc:
raise Invalid(self, self.exc)
return val
class DummyValidator(object):
def __init__(self, msg=None):
self.msg = msg
def __call__(self, node, value):
from colander import Invalid
if self.msg:
raise Invalid(node, self.msg)
class Uncooperative(object):
def __str__(self):
raise ValueError('I wont cooperate')
__unicode__ = __str__
class DummyType(object):
def serialize(self, node, value):
return value
def deserialize(self, node, value):
return value