Select Git revision
test_typedcols.py 5.47 KiB
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016, CESNET, z. s. p. o.
# Use of this source is governed by an ISC license, see LICENSE file.
from typedcols import TypedDict, OpenTypedDict, TypedList, KeyNotAllowed, KeysRequired, Discard, Any
from sys import version_info
import unittest
address_typedef = {
"street": {"type": str},
"num": {"type": int, "description": "Street number"},
"city": str,
"state": {"type": str, "required": True}
}
class AddressDict(TypedDict):
typedef = address_typedef
allow_unknown = True
def raise_discard(x=None):
raise Discard
person_typedef = {
"name": {"type": str, "default": "_Default_Value_"},
"age": int,
"address": {"type": AddressDict},
"tel": {"type": int, "required": True},
"note": {},
"discard1": Discard,
"discard2": {"type": Discard, "default": "asdf"},
"discard3": lambda x: Discard,
"discard4": raise_discard,
"discard_default1": {"type": Any, "default": Discard}, # Same as no default
"discard_default2": {"type": Any, "default": raise_discard}, # Same as no default
}
person_init_data = {
"age": "34",
"note": None,
"address": {
"street": "Vrchlikova",
"num": 12.3,
"city": "Kocourkov",
"unknown": "blah"
},
"discard1": "junk",
"discard2": "garbage",
"discard3": "rubbish",
"discard4": "scrap"
}
class PersonDict(TypedDict):
typedef = person_typedef
allow_unknown = False
# Monkeypatching for cheap Py 2 & 3 compatibility
if not hasattr(unittest.TestCase, "assertRaisesRegex"):
unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
class TestTypedDict(unittest.TestCase):
def setUp(self):
self.person = PersonDict(person_init_data)
def testTypedefNormalization(self):
self.assertEqual(self.person.typedef["age"], {"type": int})
def testInit(self):
self.assertEqual(self.person, {
"name": "_Default_Value_",
"age": 34,
"note": None,
"address": {
"street": "Vrchlikova",
"num": 12,
"city": "Kocourkov",
"unknown": "blah"}})
def testSetGetKnownOk(self):
self.person["address"]["city"] = "Brno"
self.assertEqual(self.person["address"]["city"], "Brno")
def testSetKnownBadType(self):
with self.assertRaisesRegex(ValueError, r"\(\('num',\), \"invalid literal for int\(\) with base 10: 'WRONG'\", 'Street number'\)"):
self.person["address"]["num"] = "WRONG"
def testUpdate(self):
self.person.clear()
with self.assertRaisesRegex(ValueError, r"\(\('age',\), \"invalid literal for int\(\) with base 10: 'bla'\"\)"):
self.person.update({
"age": "bla"
})
def testUpdateNested(self):
self.person.clear()
with self.assertRaisesRegex(ValueError, r"\(\('address', 'num'\), \"invalid literal for int\(\) with base 10: 'asdf'\", 'Street number'\)"):
self.person.update({
"address": {
"num": "asdf"
}
})
def testRequired(self):
with self.assertRaisesRegex(KeysRequired, r"\(\('tel',\), \('address', 'state'\)\)|\(\('address', 'state'\), \('tel',\)\)"):
self.person.checkRequired(recursive=True)
def testUnknown(self):
with self.assertRaisesRegex(KeyNotAllowed, r'unknown'):
self.person["unknown"] = "WRONG"
def testDel(self):
del self.person["address"]["city"]
with self.assertRaisesRegex(KeyError, r"'city'"):
self.person["address"]["city"]
def testDelDefault(self):
del self.person["name"]
self.assertEqual(self.person["name"], "_Default_Value_")
def testIter(self):
try:
it = self.person.iteritems()
except AttributeError:
it = self.person.items()
res = sorted([v for v in it])
self.assertEqual(res, [
("address", {"city": "Kocourkov", "street": "Vrchlikova", "num": 12, "unknown": "blah"}),
("age", 34),
("name", "_Default_Value_"),
("note", None)
])
class TestOpenTypedDict(TestTypedDict):
def setUp(self):
open_address_dict = OpenTypedDict(typedef=address_typedef.copy(), allow_unknown=True)
open_person_typedef = person_typedef.copy()
open_person_typedef["address"] = open_address_dict
open_person_dict = OpenTypedDict(typedef=open_person_typedef)
self.person = open_person_dict(person_init_data)
class IntList(TypedList):
item_type = int
class TestTypedList(unittest.TestCase):
def setUp(self):
self.intlist = IntList((1, 2.1, "3"))
def testInit(self):
self.assertEqual(list(self.intlist), [1, 2, 3])
def testSetGetKnownOk(self):
self.intlist[2] = "4"
self.assertEqual(self.intlist[-1], 4)
def testSetKnownBadType(self):
with self.assertRaisesRegex(ValueError, r"invalid literal for int\(\) with base 10: 'WRONG'"):
self.intlist[2] = "WRONG"
def testDel(self):
del self.intlist[1]
self.assertEqual(list(self.intlist), [1, 3])
def testDelOutOfBounds(self):
with self.assertRaisesRegex(IndexError, r"list assignment index out of range"):
del self.intlist[3]
def testIter(self):
res = [val for val in self.intlist]
self.assertEqual(res, [1, 2, 3])
if __name__ == '__main__':
unittest.main()