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, struct, msg=None, pos=None): from colander import Invalid exc = Invalid(struct, msg) exc.pos = pos return exc def test_ctor(self): exc = self._makeOne(None, 'msg') self.assertEqual(exc.struct, None) self.assertEqual(exc.msg, 'msg') self.assertEqual(exc.children, []) def test_add(self): exc = self._makeOne(None, 'msg') other = Dummy() exc.add(other) self.assertEqual(other.parent, exc) self.assertEqual(exc.children, [other]) def test__keyname_no_parent(self): struct = DummyStructure(None, name='name') exc = self._makeOne(None, '') exc.struct = struct self.assertEqual(exc._keyname(), 'name') def test__keyname_positional_parent(self): from colander import Positional parent = Dummy() parent.struct = DummyStructure(Positional()) exc = self._makeOne(None, '') exc.parent = parent exc.pos = 2 self.assertEqual(exc._keyname(), '2') def test__keyname_nonpositional_parent(self): parent = Dummy() parent.struct = DummyStructure(None) exc = self._makeOne(None, 'me') exc.parent = parent exc.pos = 2 exc.struct = DummyStructure(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 struct1 = DummyStructure(None, 'struct1') struct2 = DummyStructure(Positional(), 'struct2') struct3 = DummyStructure(Positional(), 'struct3') struct4 = DummyStructure(Positional(), 'struct4') exc1 = self._makeOne(struct1, 'exc1', pos=1) exc2 = self._makeOne(struct2, 'exc2', pos=2) exc3 = self._makeOne(struct3, 'exc3', pos=3) exc4 = self._makeOne(struct4, 'exc4', pos=4) exc1.add(exc2) exc2.add(exc3) exc1.add(exc4) d = exc1.asdict() self.assertEqual(d, {'struct1.struct2.3': 'exc1; exc2; exc3', 'struct1.struct4': 'exc1; exc4'}) 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 TestRange(unittest.TestCase): def _makeOne(self, min=None, max=None): from colander import Range return Range(min=min, max=max) 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, '0 is less than minimum value 1') def test_max_failure(self): validator = self._makeOne(max=1) e = invalid_exc(validator, None, 2) self.assertEqual(e.msg, '2 is greater than maximum value 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]) e = invalid_exc(validator, None, None) self.assertEqual(e.msg, 'None is not one of [1]') class TestMapping(unittest.TestCase): def _makeOne(self, unknown_keys='ignore'): from colander import Mapping return Mapping(unknown_keys=unknown_keys) def test_ctor_bad_unknown_keys(self): self.assertRaises(ValueError, self._makeOne, 'badarg') def test_ctor_good_unknown_keys(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): struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, None) self.assertEqual( e.msg, 'None is not a mapping type: iteration over non-sequence') def test_deserialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, {}) self.assertEqual(result, {}) def test_deserialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() result = typ.deserialize(struct, {'a':1}) self.assertEqual(result, {'a':1}) def test_deserialize_unknown_keys_raise(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne('raise') e = invalid_exc(typ.deserialize, struct, {'a':1, 'b':2}) self.assertEqual(e.msg, "Unrecognized keys in mapping: {'b': 2}") def test_deserialize_unknown_keys_preserve(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne('preserve') result = typ.deserialize(struct, {'a':1, 'b':2}) self.assertEqual(result, {'a':1, 'b':2}) def test_deserialize_substructs_raise(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a', exc='Wrong 2'), DummyStructure(None, name='b', exc='Wrong 2'), ] typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, {'a':1, 'b':2}) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) def test_deserialize_substruct_missing_default(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a'), DummyStructure(None, name='b', default='abc'), ] typ = self._makeOne() result = typ.deserialize(struct, {'a':1}) self.assertEqual(result, {'a':1, 'b':'abc'}) def test_deserialize_substruct_missing_nodefault(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a'), DummyStructure(None, name='b'), ] typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, {'a':1}) self.assertEqual(e.children[0].msg, "'b' is required but missing") def test_serialize_not_a_mapping(self): struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.serialize, struct, None) self.assertEqual( e.msg, 'None is not a mapping type: iteration over non-sequence') def test_serialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne() result = typ.serialize(struct, {}) self.assertEqual(result, {}) def test_serialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() result = typ.serialize(struct, {'a':1}) self.assertEqual(result, {'a':1}) def test_serialize_unknown_keys_raise(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne('raise') e = invalid_exc(typ.serialize, struct, {'a':1, 'b':2}) self.assertEqual(e.msg, "Unrecognized keys in mapping: {'b': 2}") def test_serialize_unknown_keys_preserve(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne('preserve') result = typ.serialize(struct, {'a':1, 'b':2}) self.assertEqual(result, {'a':1, 'b':2}) def test_serialize_substructs_raise(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a', exc='Wrong 2'), DummyStructure(None, name='b', exc='Wrong 2'), ] typ = self._makeOne() e = invalid_exc(typ.serialize, struct, {'a':1, 'b':2}) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) def test_serialize_substruct_missing_default(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a'), DummyStructure(None, name='b', default='abc'), ] typ = self._makeOne() result = typ.serialize(struct, {'a':1}) self.assertEqual(result, {'a':1, 'b':'abc'}) def test_serialize_substruct_missing_nodefault(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a'), DummyStructure(None, name='b'), ] typ = self._makeOne() e = invalid_exc(typ.serialize, struct, {'a':1}) self.assertEqual(e.children[0].msg, "'b' is required but missing") class TestTuple(unittest.TestCase): def _makeOne(self): from colander import Tuple return Tuple() def test_deserialize_not_iterable(self): struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, None) self.assertEqual( e.msg, 'None is not iterable') self.assertEqual(e.struct, struct) def test_deserialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, ()) self.assertEqual(result, ()) def test_deserialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() result = typ.deserialize(struct, ('a',)) self.assertEqual(result, ('a',)) def test_deserialize_toobig(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, ('a','b')) self.assertEqual(e.msg, "('a', 'b') has an incorrect number of elements (expected 1, was 2)") def test_deserialize_toosmall(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, ()) self.assertEqual(e.msg, "() has an incorrect number of elements (expected 1, was 0)") def test_deserialize_substructs_raise(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a', exc='Wrong 2'), DummyStructure(None, name='b', exc='Wrong 2'), ] typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, ('1', '2')) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) def test_serialize_not_iterable(self): struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.serialize, struct, None) self.assertEqual( e.msg, 'None is not iterable') self.assertEqual(e.struct, struct) def test_serialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne() result = typ.serialize(struct, ()) self.assertEqual(result, ()) def test_serialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() result = typ.serialize(struct, ('a',)) self.assertEqual(result, ('a',)) def test_serialize_toobig(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() e = invalid_exc(typ.serialize, struct, ('a','b')) self.assertEqual(e.msg, "('a', 'b') has an incorrect number of elements (expected 1, was 2)") def test_serialize_toosmall(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne() e = invalid_exc(typ.serialize, struct, ()) self.assertEqual(e.msg, "() has an incorrect number of elements (expected 1, was 0)") def test_serialize_substructs_raise(self): struct = DummyStructure(None) struct.structs = [ DummyStructure(None, name='a', exc='Wrong 2'), DummyStructure(None, name='b', exc='Wrong 2'), ] typ = self._makeOne() e = invalid_exc(typ.serialize, struct, ('1', '2')) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) class TestSequence(unittest.TestCase): def _makeOne(self, substruct): from colander import Sequence return Sequence(substruct) def test_alias(self): from colander import Seq from colander import Sequence self.assertEqual(Seq, Sequence) def test_deserialize_not_iterable(self): struct = DummyStructure(None) typ = self._makeOne(struct) e = invalid_exc(typ.deserialize, struct, None) self.assertEqual( e.msg, 'None is not iterable') self.assertEqual(e.struct, struct) def test_deserialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne(struct) result = typ.deserialize(struct, ()) self.assertEqual(result, []) def test_deserialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne(struct) result = typ.deserialize(struct, ('a',)) self.assertEqual(result, ['a']) def test_deserialize_substructs_raise(self): struct = DummyStructure(None, exc='Wrong') typ = self._makeOne(struct) e = invalid_exc(typ.deserialize, struct, ('1', '2')) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) def test_serialize_not_iterable(self): struct = DummyStructure(None) typ = self._makeOne(struct) e = invalid_exc(typ.serialize, struct, None) self.assertEqual( e.msg, 'None is not iterable') self.assertEqual(e.struct, struct) def test_serialize_no_substructs(self): struct = DummyStructure(None) typ = self._makeOne(struct) result = typ.serialize(struct, ()) self.assertEqual(result, []) def test_serialize_ok(self): struct = DummyStructure(None) struct.structs = [DummyStructure(None, name='a')] typ = self._makeOne(struct) result = typ.serialize(struct, ('a',)) self.assertEqual(result, ['a']) def test_serialize_substructs_raise(self): struct = DummyStructure(None, exc='Wrong') typ = self._makeOne(struct) e = invalid_exc(typ.serialize, struct, ('1', '2')) self.assertEqual(e.msg, None) self.assertEqual(len(e.children), 2) class TestString(unittest.TestCase): def _makeOne(self, encoding='utf-8'): 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_uncooperative(self): val = Uncooperative() struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, val) self.failUnless(e.msg) def test_deserialize_unicode(self): uni = u'\xf8' struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, uni) self.assertEqual(result, uni) def test_deserialize_from_utf8(self): utf8 = '\xc3\xb8' uni = u'\xf8' struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, utf8) self.assertEqual(result, uni) def test_deserialize_from_utf16(self): utf16 = '\xff\xfe\xf8\x00' uni = u'\xf8' struct = DummyStructure(None) typ = self._makeOne('utf-16') result = typ.deserialize(struct, utf16) self.assertEqual(result, uni) def test_serialize_uncooperative(self): val = Uncooperative() struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.serialize, struct, val) self.failUnless(e.msg) def test_serialize_to_utf8(self): utf8 = '\xc3\xb8' uni = u'\xf8' struct = DummyStructure(None) typ = self._makeOne() result = typ.serialize(struct, uni) self.assertEqual(result, utf8) def test_serialize_to_utf16(self): utf16 = '\xff\xfe\xf8\x00' uni = u'\xf8' struct = DummyStructure(None) typ = self._makeOne('utf-16') result = typ.serialize(struct, uni) self.assertEqual(result, utf16) 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_deserialize_fails(self): val = 'P' struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, val) self.failUnless(e.msg) def test_deserialize_ok(self): val = '1' struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, val) self.assertEqual(result, 1) def test_serialize_fails(self): val = 'P' struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.serialize, struct, val) self.failUnless(e.msg) def test_serialize_ok(self): val = 1 struct = DummyStructure(None) typ = self._makeOne() result = typ.serialize(struct, val) self.assertEqual(result, '1') class TestFloat(unittest.TestCase): def _makeOne(self): from colander import Float return Float() def test_deserialize_fails(self): val = 'P' struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.deserialize, struct, val) self.failUnless(e.msg) def test_deserialize_ok(self): val = '1.0' struct = DummyStructure(None) typ = self._makeOne() result = typ.deserialize(struct, val) self.assertEqual(result, 1.0) def test_serialize_fails(self): val = 'P' struct = DummyStructure(None) typ = self._makeOne() e = invalid_exc(typ.serialize, struct, val) self.failUnless(e.msg) def test_serialize_ok(self): val = 1.0 struct = DummyStructure(None) typ = self._makeOne() result = typ.serialize(struct, 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_deserialize(self): typ = self._makeOne() struct = DummyStructure(None) self.assertEqual(typ.deserialize(struct, 'false'), False) self.assertEqual(typ.deserialize(struct, 'FALSE'), False) self.assertEqual(typ.deserialize(struct, '0'), False) self.assertEqual(typ.deserialize(struct, 'true'), True) self.assertEqual(typ.deserialize(struct, 'other'), True) def test_deserialize_unstringable(self): typ = self._makeOne() struct = DummyStructure(None) e = invalid_exc(typ.deserialize, struct, Uncooperative()) self.failUnless(e.msg.endswith('not a string')) def test_serialize(self): typ = self._makeOne() struct = DummyStructure(None) self.assertEqual(typ.serialize(struct, 1), 'true') self.assertEqual(typ.serialize(struct, True), 'true') self.assertEqual(typ.serialize(struct, None), 'false') self.assertEqual(typ.serialize(struct, 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) result = typ._zope_dottedname_style(None, '.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) result = typ._zope_dottedname_style(None, '..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, "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, "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() self.assertRaises(ImportError, 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() e = invalid_exc(typ.deserialize, None, None) self.assertEqual(e.msg, "None is not a string") def test_deserialize_using_pkgresources_style(self): typ = self._makeOne() result = typ.deserialize(None, 'colander.tests:TestGlobalObject') self.assertEqual(result, self.__class__) def test_deserialize_using_zope_dottedname_style(self): typ = self._makeOne() result = typ.deserialize(None, 'colander.tests.TestGlobalObject') self.assertEqual(result, self.__class__) def test_deserialize_style_raises(self): typ = self._makeOne() e = invalid_exc(typ.deserialize, None, 'cant.be.found') self.assertEqual(e.msg, "The dotted name 'cant.be.found' cannot be imported") def test_serialize_ok(self): import colander.tests typ = self._makeOne() result = typ.serialize(None, colander.tests) self.assertEqual(result, 'colander.tests') def test_serialize_fail(self): typ = self._makeOne() e = invalid_exc(typ.serialize, None, None) self.assertEqual(e.msg, 'None has no __name__') class TestStructure(unittest.TestCase): def _makeOne(self, *arg, **kw): from colander import Structure return Structure(*arg, **kw) def test_new_sets_order(self): structure = self._makeOne(None) self.failUnless(hasattr(structure, '_order')) def test_ctor(self): structure = self._makeOne(None, 0, validator=1, default=2, name=3) self.assertEqual(structure.typ, None) self.assertEqual(structure.structs, [0]) self.assertEqual(structure.validator, 1) self.assertEqual(structure.default, 2) self.assertEqual(structure.name, 3) def test_required_true(self): structure = self._makeOne(None) self.assertEqual(structure.required, True) def test_required_false(self): structure = self._makeOne(None, default=1) self.assertEqual(structure.required, False) def test_deserialize_no_validator(self): typ = DummyType() structure = self._makeOne(typ) result = structure.deserialize(1) self.assertEqual(result, 1) def test_deserialize_with_validator(self): typ = DummyType() validator = DummyValidator(msg='Wrong') structure = self._makeOne(typ, validator=validator) e = invalid_exc(structure.deserialize, 1) self.assertEqual(e.msg, 'Wrong') def test_serialize(self): typ = DummyType() structure = self._makeOne(typ) result = structure.serialize(1) self.assertEqual(result, 1) def test_add(self): structure = self._makeOne(None) structure.add(1) self.assertEqual(structure.structs, [1]) 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 = colander.Structure(colander.String()) structure = MySchema(unknown_keys='raise') self.failUnless(hasattr(structure, '_order')) self.assertEqual(structure.__class__, colander.Structure) self.assertEqual(structure.typ.__class__, colander.Mapping) self.assertEqual(structure.typ.unknown_keys, 'raise') self.assertEqual(structure.structs[0].typ.__class__, colander.String) class TestSequenceSchema(unittest.TestCase): def test_it(self): import colander class MySchema(colander.SequenceSchema): pass inner = colander.Structure(colander.String()) structure = MySchema(inner) self.failUnless(hasattr(structure, '_order')) self.assertEqual(structure.__class__, colander.Structure) self.assertEqual(structure.typ.__class__, colander.Sequence) self.assertEqual(structure.typ.struct, inner) class TestTupleSchema(unittest.TestCase): def test_it(self): import colander class MySchema(colander.TupleSchema): thing = colander.Structure(colander.String()) structure = MySchema() self.failUnless(hasattr(structure, '_order')) self.assertEqual(structure.__class__, colander.Structure) self.assertEqual(structure.typ.__class__, colander.Tuple) self.assertEqual(structure.structs[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.Structure( colander.Integer(), name='int', validator=colander.Range(0, 10) ) ob = colander.Structure( colander.GlobalObject(package=colander), name='ob', ) tup = colander.Structure( colander.Tuple(), colander.Structure( colander.Integer(), name='tupint', ), colander.Structure( colander.String(), name='tupstring', ), name='tup', ) seq = colander.Structure( colander.Sequence(tup), name='seq', ) seq2 = colander.Structure( colander.Sequence( colander.Structure( colander.Mapping(), colander.Structure( colander.Integer(), name='key', ), colander.Structure( colander.Integer(), name='key2', ), name='mapping', ) ), name='seq2', ) schema = colander.Structure( 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.Structure(colander.Int()) tupstring = colander.Structure(colander.String()) class MappingSchema(colander.MappingSchema): key = colander.Structure(colander.Int()) key2 = colander.Structure(colander.Int()) class MainSchema(colander.MappingSchema): int = colander.Structure(colander.Int(), validator=colander.Range(0, 10)) ob = colander.Structure(colander.GlobalObject(package=colander)) seq = colander.Structure(colander.Sequence(TupleSchema())) tup = TupleSchema() seq2 = colander.SequenceSchema(MappingSchema()) schema = MainSchema() return schema class Dummy(object): pass class DummyStructure(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.structs = [] 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, struct, value): from colander import Invalid if self.msg: raise Invalid(struct, self.msg) class Uncooperative(object): def __str__(self): raise ValueError('I wont cooperate') __unicode__ = __str__ class DummyType(object): def serialize(self, struct, value): return value def deserialize(self, struct, value): return value