[Python-modules-commits] [voluptuous] 07/08: merge patched into master
Barry Warsaw
barry at moszumanska.debian.org
Tue Aug 2 19:01:49 UTC 2016
This is an automated email from the git hooks/post-receive script.
barry pushed a commit to branch master
in repository voluptuous.
commit 5dc2a2112308d96e33fb13a7d00a783775a36446
Merge: b1fb42e 466520f
Author: Barry Warsaw <barry at ubuntu.com>
Date: Tue Aug 2 14:57:53 2016 -0400
merge patched into master
debian/.git-dpm | 4 ++--
debian/patches/0002-Include-tests-package.patch | 22 ----------------------
debian/patches/restore-tests.patch | 18 ++++++++++++++++--
debian/patches/series | 1 -
4 files changed, 18 insertions(+), 27 deletions(-)
diff --cc debian/.git-dpm
index 0f4c484,0000000..3142761
mode 100644,000000..100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@@ -1,11 -1,0 +1,11 @@@
+# see git-dpm(1) from git-dpm package
- e6f20941122c3856dea65da703d0ae105ea8aa22
- e6f20941122c3856dea65da703d0ae105ea8aa22
++466520f320160206832e09b2e67990e4c2a1393b
++466520f320160206832e09b2e67990e4c2a1393b
+96e09f6d760c570a65be150fa542abdad75f8d71
+96e09f6d760c570a65be150fa542abdad75f8d71
+voluptuous_0.9.2.orig.tar.gz
+bb4924485f70be72a2c28a1a24f007108f8b8da1
+29857
+debianTag="debian/%e%v"
+patchedTag="patched/%e%v"
+upstreamTag="upstream/%e%u"
diff --cc debian/patches/restore-tests.patch
index cd64946,0000000..1c5e51d
mode 100644,000000..100644
--- a/debian/patches/restore-tests.patch
+++ b/debian/patches/restore-tests.patch
@@@ -1,726 -1,0 +1,740 @@@
- From 16548658044a65ca84051912460826694f97bebe Mon Sep 17 00:00:00 2001
++From 466520f320160206832e09b2e67990e4c2a1393b Mon Sep 17 00:00:00 2001
+From: Barry Warsaw <barry at ubuntu.com>
+Date: Tue, 2 Aug 2016 14:05:07 -0400
+Subject: Add the tests which are missing from PyPI tarball.
+
+Bug: https://github.com/alecthomas/voluptuous/issues/188
+Forwarded: not-needed
+
+Patch-Name: restore-tests.patch
+---
++ setup.py | 2 +-
+ voluptuous/tests/__init__.py | 1 +
+ voluptuous/tests/tests.md | 268 +++++++++++++++++++++++++++
+ voluptuous/tests/tests.py | 421 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 690 insertions(+)
++ 4 files changed, 691 insertions(+), 1 deletion(-)
+ create mode 100644 voluptuous/tests/__init__.py
+ create mode 100644 voluptuous/tests/tests.md
+ create mode 100644 voluptuous/tests/tests.py
+
++diff --git a/setup.py b/setup.py
++index 6140253..4d6275d 100644
++--- a/setup.py
+++++ b/setup.py
++@@ -32,7 +32,7 @@ setup(
++ long_description=long_description,
++ license='BSD',
++ platforms=['any'],
++- packages=['voluptuous'],
+++ packages=['voluptuous', 'voluptuous.tests'],
++ author='Alec Thomas',
++ author_email='alec at swapoff.org',
++ classifiers=[
+diff --git a/voluptuous/tests/__init__.py b/voluptuous/tests/__init__.py
+new file mode 100644
+index 0000000..f29719c
+--- /dev/null
++++ b/voluptuous/tests/__init__.py
+@@ -0,0 +1 @@
++__author__ = 'tusharmakkar08'
+diff --git a/voluptuous/tests/tests.md b/voluptuous/tests/tests.md
+new file mode 100644
+index 0000000..18f6fba
+--- /dev/null
++++ b/voluptuous/tests/tests.md
+@@ -0,0 +1,268 @@
++Error reporting should be accurate:
++
++ >>> from voluptuous import *
++ >>> schema = Schema(['one', {'two': 'three', 'four': ['five'],
++ ... 'six': {'seven': 'eight'}}])
++ >>> schema(['one'])
++ ['one']
++ >>> schema([{'two': 'three'}])
++ [{'two': 'three'}]
++
++It should show the exact index and container type, in this case a list
++value:
++
++ >>> try:
++ ... schema(['one', 'two'])
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc) == 'expected a dictionary @ data[1]'
++ True
++
++It should also be accurate for nested values:
++
++ >>> try:
++ ... schema([{'two': 'nine'}])
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "not a valid value for dictionary value @ data[0]['two']"
++
++ >>> try:
++ ... schema([{'four': ['nine']}])
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "not a valid value @ data[0]['four'][0]"
++
++ >>> try:
++ ... schema([{'six': {'seven': 'nine'}}])
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "not a valid value for dictionary value @ data[0]['six']['seven']"
++
++Errors should be reported depth-first:
++
++ >>> validate = Schema({'one': {'two': 'three', 'four': 'five'}})
++ >>> try:
++ ... validate({'one': {'four': 'six'}})
++ ... except Invalid as e:
++ ... print(e)
++ ... print(e.path)
++ not a valid value for dictionary value @ data['one']['four']
++ ['one', 'four']
++
++Voluptuous supports validation when extra fields are present in the
++data:
++
++ >>> schema = Schema({'one': 1, Extra: object})
++ >>> schema({'two': 'two', 'one': 1}) == {'two': 'two', 'one': 1}
++ True
++ >>> schema = Schema({'one': 1})
++ >>> try:
++ ... schema({'two': 2})
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "extra keys not allowed @ data['two']"
++
++dict, list, and tuple should be available as type validators:
++
++ >>> Schema(dict)({'a': 1, 'b': 2}) == {'a': 1, 'b': 2}
++ True
++ >>> Schema(list)([1,2,3])
++ [1, 2, 3]
++ >>> Schema(tuple)((1,2,3))
++ (1, 2, 3)
++
++Validation should return instances of the right types when the types are
++subclasses of dict or list:
++
++ >>> class Dict(dict):
++ ... pass
++ >>>
++ >>> d = Schema(dict)(Dict(a=1, b=2))
++ >>> d == {'a': 1, 'b': 2}
++ True
++ >>> type(d) is Dict
++ True
++ >>> class List(list):
++ ... pass
++ >>>
++ >>> l = Schema(list)(List([1,2,3]))
++ >>> l
++ [1, 2, 3]
++ >>> type(l) is List
++ True
++
++Multiple errors are reported:
++
++ >>> schema = Schema({'one': 1, 'two': 2})
++ >>> try:
++ ... schema({'one': 2, 'two': 3, 'three': 4})
++ ... except MultipleInvalid as e:
++ ... errors = sorted(e.errors, key=lambda k: str(k))
++ ... print([str(i) for i in errors]) # doctest: +NORMALIZE_WHITESPACE
++ ["extra keys not allowed @ data['three']",
++ "not a valid value for dictionary value @ data['one']",
++ "not a valid value for dictionary value @ data['two']"]
++ >>> schema = Schema([[1], [2], [3]])
++ >>> try:
++ ... schema([1, 2, 3])
++ ... except MultipleInvalid as e:
++ ... print([str(i) for i in e.errors]) # doctest: +NORMALIZE_WHITESPACE
++ ['expected a list @ data[0]',
++ 'expected a list @ data[1]',
++ 'expected a list @ data[2]']
++
++Required fields in dictionary which are invalid should not have required :
++
++ >>> from voluptuous import *
++ >>> schema = Schema({'one': {'two': 3}}, required=True)
++ >>> try:
++ ... schema({'one': {'two': 2}})
++ ... except MultipleInvalid as e:
++ ... errors = e.errors
++ >>> 'required' in ' '.join([x.msg for x in errors])
++ False
++
++Multiple errors for nested fields in dicts and objects:
++
++> \>\>\> from collections import namedtuple \>\>\> validate = Schema({
++> ... 'anobject': Object({ ... 'strfield': str, ... 'intfield': int ...
++> }) ... }) \>\>\> try: ... SomeObj = namedtuple('SomeObj', ('strfield',
++> 'intfield')) ... validate({'anobject': SomeObj(strfield=123,
++> intfield='one')}) ... except MultipleInvalid as e: ...
++> print(sorted(str(i) for i in e.errors)) \# doctest:
++> +NORMALIZE\_WHITESPACE ["expected int for object value @
++> data['anobject']['intfield']", "expected str for object value @
++> data['anobject']['strfield']"]
++
++Custom classes validate as schemas:
++
++ >>> class Thing(object):
++ ... pass
++ >>> schema = Schema(Thing)
++ >>> t = schema(Thing())
++ >>> type(t) is Thing
++ True
++
++Classes with custom metaclasses should validate as schemas:
++
++ >>> class MyMeta(type):
++ ... pass
++ >>> class Thing(object):
++ ... __metaclass__ = MyMeta
++ >>> schema = Schema(Thing)
++ >>> t = schema(Thing())
++ >>> type(t) is Thing
++ True
++
++Schemas built with All() should give the same error as the original
++validator (Issue \#26):
++
++ >>> schema = Schema({
++ ... Required('items'): All([{
++ ... Required('foo'): str
++ ... }])
++ ... })
++
++ >>> try:
++ ... schema({'items': [{}]})
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "required key not provided @ data['items'][0]['foo']"
++
++Validator should return same instance of the same type for object:
++
++ >>> class Structure(object):
++ ... def __init__(self, q=None):
++ ... self.q = q
++ ... def __repr__(self):
++ ... return '{0.__name__}(q={1.q!r})'.format(type(self), self)
++ ...
++ >>> schema = Schema(Object({'q': 'one'}, cls=Structure))
++ >>> type(schema(Structure(q='one'))) is Structure
++ True
++
++Object validator should treat cls argument as optional. In this case it
++shouldn't check object type:
++
++ >>> from collections import namedtuple
++ >>> NamedTuple = namedtuple('NamedTuple', ('q',))
++ >>> schema = Schema(Object({'q': 'one'}))
++ >>> named = NamedTuple(q='one')
++ >>> schema(named) == named
++ True
++ >>> schema(named)
++ NamedTuple(q='one')
++
++If cls argument passed to object validator we should check object type:
++
++ >>> schema = Schema(Object({'q': 'one'}, cls=Structure))
++ >>> schema(NamedTuple(q='one')) # doctest: +IGNORE_EXCEPTION_DETAIL
++ Traceback (most recent call last):
++ ...
++ MultipleInvalid: expected a <class 'Structure'>
++ >>> schema = Schema(Object({'q': 'one'}, cls=NamedTuple))
++ >>> schema(NamedTuple(q='one'))
++ NamedTuple(q='one')
++
++Ensure that objects with \_\_slots\_\_ supported properly:
++
++ >>> class SlotsStructure(Structure):
++ ... __slots__ = ['q']
++ ...
++ >>> schema = Schema(Object({'q': 'one'}))
++ >>> schema(SlotsStructure(q='one'))
++ SlotsStructure(q='one')
++ >>> class DictStructure(object):
++ ... __slots__ = ['q', '__dict__']
++ ... def __init__(self, q=None, page=None):
++ ... self.q = q
++ ... self.page = page
++ ... def __repr__(self):
++ ... return '{0.__name__}(q={1.q!r}, page={1.page!r})'.format(type(self), self)
++ ...
++ >>> structure = DictStructure(q='one')
++ >>> structure.page = 1
++ >>> try:
++ ... schema(structure)
++ ... raise AssertionError('MultipleInvalid not raised')
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> str(exc)
++ "extra keys not allowed @ data['page']"
++
++ >>> schema = Schema(Object({'q': 'one', Extra: object}))
++ >>> schema(structure)
++ DictStructure(q='one', page=1)
++
++Ensure that objects can be used with other validators:
++
++ >>> schema = Schema({'meta': Object({'q': 'one'})})
++ >>> schema({'meta': Structure(q='one')})
++ {'meta': Structure(q='one')}
++
++Ensure that subclasses of Invalid of are raised as is.
++
++ >>> class SpecialInvalid(Invalid):
++ ... pass
++ ...
++ >>> def custom_validator(value):
++ ... raise SpecialInvalid('boom')
++ ...
++ >>> schema = Schema({'thing': custom_validator})
++ >>> try:
++ ... schema({'thing': 'not an int'})
++ ... except MultipleInvalid as e:
++ ... exc = e
++ >>> exc.errors[0].__class__.__name__
++ 'SpecialInvalid'
+diff --git a/voluptuous/tests/tests.py b/voluptuous/tests/tests.py
+new file mode 100644
+index 0000000..2b77272
+--- /dev/null
++++ b/voluptuous/tests/tests.py
+@@ -0,0 +1,421 @@
++import copy
++from nose.tools import assert_equal, assert_raises
++
++from voluptuous import (
++ Schema, Required, Extra, Invalid, In, Remove, Literal,
++ Url, MultipleInvalid, LiteralInvalid, NotIn, Match, Email,
++ Replace, Range, Coerce, All, Any, Length, FqdnUrl, ALLOW_EXTRA, PREVENT_EXTRA,
++ validate_schema,
++)
++from voluptuous.humanize import humanize_error
++
++
++def test_required():
++ """Verify that Required works."""
++ schema = Schema({Required('q'): 1})
++ # Can't use nose's raises (because we need to access the raised
++ # exception, nor assert_raises which fails with Python 2.6.9.
++ try:
++ schema({})
++ except Invalid as e:
++ assert_equal(str(e), "required key not provided @ data['q']")
++ else:
++ assert False, "Did not raise Invalid"
++
++
++def test_extra_with_required():
++ """Verify that Required does not break Extra."""
++ schema = Schema({Required('toaster'): str, Extra: object})
++ r = schema({'toaster': 'blue', 'another_valid_key': 'another_valid_value'})
++ assert_equal(
++ r, {'toaster': 'blue', 'another_valid_key': 'another_valid_value'})
++
++
++def test_iterate_candidates():
++ """Verify that the order for iterating over mapping candidates is right."""
++ schema = {
++ "toaster": str,
++ Extra: object,
++ }
++ # toaster should be first.
++ from voluptuous.schema_builder import _iterate_mapping_candidates
++ assert_equal(_iterate_mapping_candidates(schema)[0][0], 'toaster')
++
++
++def test_in():
++ """Verify that In works."""
++ schema = Schema({"color": In(frozenset(["blue", "red", "yellow"]))})
++ schema({"color": "blue"})
++
++
++def test_not_in():
++ """Verify that NotIn works."""
++ schema = Schema({"color": NotIn(frozenset(["blue", "red", "yellow"]))})
++ schema({"color": "orange"})
++ try:
++ schema({"color": "blue"})
++ except Invalid as e:
++ assert_equal(str(e), "value is not allowed for dictionary value @ data['color']")
++ else:
++ assert False, "Did not raise NotInInvalid"
++
++
++def test_remove():
++ """Verify that Remove works."""
++ # remove dict keys
++ schema = Schema({"weight": int,
++ Remove("color"): str,
++ Remove("amount"): int})
++ out_ = schema({"weight": 10, "color": "red", "amount": 1})
++ assert "color" not in out_ and "amount" not in out_
++
++ # remove keys by type
++ schema = Schema({"weight": float,
++ "amount": int,
++ # remvove str keys with int values
++ Remove(str): int,
++ # keep str keys with str values
++ str: str})
++ out_ = schema({"weight": 73.4,
++ "condition": "new",
++ "amount": 5,
++ "left": 2})
++ # amount should stay since it's defined
++ # other string keys with int values will be removed
++ assert "amount" in out_ and "left" not in out_
++ # string keys with string values will stay
++ assert "condition" in out_
++
++ # remove value from list
++ schema = Schema([Remove(1), int])
++ out_ = schema([1, 2, 3, 4, 1, 5, 6, 1, 1, 1])
++ assert_equal(out_, [2, 3, 4, 5, 6])
++
++ # remove values from list by type
++ schema = Schema([1.0, Remove(float), int])
++ out_ = schema([1, 2, 1.0, 2.0, 3.0, 4])
++ assert_equal(out_, [1, 2, 1.0, 4])
++
++
++def test_extra_empty_errors():
++ schema = Schema({'a': {Extra: object}}, required=True)
++ schema({'a': {}})
++
++
++def test_literal():
++ """ test with Literal """
++
++ schema = Schema([Literal({"a": 1}), Literal({"b": 1})])
++ schema([{"a": 1}])
++ schema([{"b": 1}])
++ schema([{"a": 1}, {"b": 1}])
++
++ try:
++ schema([{"c": 1}])
++ except Invalid as e:
++ assert_equal(str(e), "{'c': 1} not match for {'b': 1} @ data[0]")
++ else:
++ assert False, "Did not raise Invalid"
++
++ schema = Schema(Literal({"a": 1}))
++ try:
++ schema({"b": 1})
++ except MultipleInvalid as e:
++ assert_equal(str(e), "{'b': 1} not match for {'a': 1}")
++ assert_equal(len(e.errors), 1)
++ assert_equal(type(e.errors[0]), LiteralInvalid)
++ else:
++ assert False, "Did not raise Invalid"
++
++
++def test_email_validation():
++ """ test with valid email """
++ schema = Schema({"email": Email()})
++ out_ = schema({"email": "example at example.com"})
++
++ assert 'example at example.com"', out_.get("url")
++
++
++def test_email_validation_with_none():
++ """ test with invalid None Email"""
++ schema = Schema({"email": Email()})
++ try:
++ schema({"email": None})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected an Email for dictionary value @ data['email']")
++ else:
++ assert False, "Did not raise Invalid for None url"
++
++
++def test_email_validation_with_empty_string():
++ """ test with empty string Email"""
++ schema = Schema({"email": Email()})
++ try:
++ schema({"email": ''})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected an Email for dictionary value @ data['email']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_email_validation_without_host():
++ """ test with empty host name in email """
++ schema = Schema({"email": Email()})
++ try:
++ schema({"email": 'a at .com'})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected an Email for dictionary value @ data['email']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_fqdn_url_validation():
++ """ test with valid fully qualified domain name url """
++ schema = Schema({"url": FqdnUrl()})
++ out_ = schema({"url": "http://example.com/"})
++
++ assert 'http://example.com/', out_.get("url")
++
++
++def test_fqdn_url_without_domain_name():
++ """ test with invalid fully qualified domain name url """
++ schema = Schema({"url": FqdnUrl()})
++ try:
++ schema({"url": "http://localhost/"})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a Fully qualified domain name URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for None url"
++
++
++def test_fqdnurl_validation_with_none():
++ """ test with invalid None FQDN url"""
++ schema = Schema({"url": FqdnUrl()})
++ try:
++ schema({"url": None})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a Fully qualified domain name URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for None url"
++
++
++def test_fqdnurl_validation_with_empty_string():
++ """ test with empty string FQDN URL """
++ schema = Schema({"url": FqdnUrl()})
++ try:
++ schema({"url": ''})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a Fully qualified domain name URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_fqdnurl_validation_without_host():
++ """ test with empty host FQDN URL """
++ schema = Schema({"url": FqdnUrl()})
++ try:
++ schema({"url": 'http://'})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a Fully qualified domain name URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_url_validation():
++ """ test with valid URL """
++ schema = Schema({"url": Url()})
++ out_ = schema({"url": "http://example.com/"})
++
++ assert 'http://example.com/', out_.get("url")
++
++
++def test_url_validation_with_none():
++ """ test with invalid None url"""
++ schema = Schema({"url": Url()})
++ try:
++ schema({"url": None})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for None url"
++
++
++def test_url_validation_with_empty_string():
++ """ test with empty string URL """
++ schema = Schema({"url": Url()})
++ try:
++ schema({"url": ''})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_url_validation_without_host():
++ """ test with empty host URL """
++ schema = Schema({"url": Url()})
++ try:
++ schema({"url": 'http://'})
++ except MultipleInvalid as e:
++ assert_equal(str(e),
++ "expected a URL for dictionary value @ data['url']")
++ else:
++ assert False, "Did not raise Invalid for empty string url"
++
++
++def test_copy_dict_undefined():
++ """ test with a copied dictionary """
++ fields = {
++ Required("foo"): int
++ }
++ copied_fields = copy.deepcopy(fields)
++
++ schema = Schema(copied_fields)
++
++ # This used to raise a `TypeError` because the instance of `Undefined`
++ # was a copy, so object comparison would not work correctly.
++ try:
++ schema({"foo": "bar"})
++ except Exception as e:
++ assert isinstance(e, MultipleInvalid)
++
++
++def test_sorting():
++ """ Expect alphabetic sorting """
++ foo = Required('foo')
++ bar = Required('bar')
++ items = [foo, bar]
++ expected = [bar, foo]
++ result = sorted(items)
++ assert result == expected
++
++
++def test_schema_extend():
++ """Verify that Schema.extend copies schema keys from both."""
++
++ base = Schema({'a': int}, required=True)
++ extension = {'b': str}
++ extended = base.extend(extension)
++
++ assert base.schema == {'a': int}
++ assert extension == {'b': str}
++ assert extended.schema == {'a': int, 'b': str}
++ assert extended.required == base.required
++ assert extended.extra == base.extra
++
++
++def test_schema_extend_overrides():
++ """Verify that Schema.extend can override required/extra parameters."""
++
++ base = Schema({'a': int}, required=True)
++ extended = base.extend({'b': str}, required=False, extra=ALLOW_EXTRA)
++
++ assert base.required is True
++ assert base.extra == PREVENT_EXTRA
++ assert extended.required is False
++ assert extended.extra == ALLOW_EXTRA
++
++
++def test_repr():
++ """Verify that __repr__ returns valid Python expressions"""
++ match = Match('a pattern', msg='message')
++ replace = Replace('you', 'I', msg='you and I')
++ range_ = Range(min=0, max=42, min_included=False,
++ max_included=False, msg='number not in range')
++ coerce_ = Coerce(int, msg="moo")
++ all_ = All('10', Coerce(int), msg='all msg')
++
++ assert_equal(repr(match), "Match('a pattern', msg='message')")
++ assert_equal(repr(replace), "Replace('you', 'I', msg='you and I')")
++ assert_equal(
++ repr(range_),
++ "Range(min=0, max=42, min_included=False, max_included=False, msg='number not in range')"
++ )
++ assert_equal(repr(coerce_), "Coerce(int, msg='moo')")
++ assert_equal(repr(all_), "All('10', Coerce(int, msg=None), msg='all msg')")
++
++
++def test_list_validation_messages():
++ """ Make sure useful error messages are available """
++
++ def is_even(value):
++ if value % 2:
++ raise Invalid('%i is not even' % value)
++ return value
++
++ schema = Schema(dict(even_numbers=[All(int, is_even)]))
++
++ try:
++ schema(dict(even_numbers=[3]))
++ except Invalid as e:
++ assert_equal(len(e.errors), 1, e.errors)
++ assert_equal(str(e.errors[0]), "3 is not even @ data['even_numbers'][0]")
++ assert_equal(str(e), "3 is not even @ data['even_numbers'][0]")
++ else:
++ assert False, "Did not raise Invalid"
++
++
++def test_nested_multiple_validation_errors():
++ """ Make sure useful error messages are available """
++
++ def is_even(value):
++ if value % 2:
++ raise Invalid('%i is not even' % value)
++ return value
++
++ schema = Schema(dict(even_numbers=All([All(int, is_even)],
++ Length(min=1))))
++
++ try:
++ schema(dict(even_numbers=[3]))
++ except Invalid as e:
++ assert_equal(len(e.errors), 1, e.errors)
++ assert_equal(str(e.errors[0]), "3 is not even @ data['even_numbers'][0]")
++ assert_equal(str(e), "3 is not even @ data['even_numbers'][0]")
++ else:
++ assert False, "Did not raise Invalid"
++
++
++def test_humanize_error():
++ data = {
++ 'a': 'not an int',
++ 'b': [123]
++ }
++ schema = Schema({
++ 'a': int,
++ 'b': [str]
++ })
++ try:
++ schema(data)
++ except MultipleInvalid as e:
++ assert_equal(
++ humanize_error(data, e),
++ "expected int for dictionary value @ data['a']. Got 'not an int'\n"
++ "expected str @ data['b'][0]. Got 123"
++ )
++ else:
++ assert False, 'Did not raise MultipleInvalid'
++
++
++def test_fix_157():
++ s = Schema(All([Any('one', 'two', 'three')]), Length(min=1))
++ assert_equal(['one'], s(['one']))
++ assert_raises(MultipleInvalid, s, ['four'])
++
++
++def test_schema_decorator():
++ @validate_schema(int)
++ def fn(arg):
++ return arg
++
++ fn(1)
++ assert_raises(Invalid, fn, 1.0)
diff --cc debian/patches/series
index 62c1f41,0000000..9511701
mode 100644,000000..100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@@ -1,2 -1,0 +1,1 @@@
+restore-tests.patch
- 0002-Include-tests-package.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/voluptuous.git
More information about the Python-modules-commits
mailing list