Unit tests
This commit is contained in:
parent
60a29a3162
commit
9ec858772a
|
@ -0,0 +1,4 @@
|
||||||
|
[run]
|
||||||
|
include=
|
||||||
|
objtools/*
|
||||||
|
tests/*
|
|
@ -5,25 +5,23 @@ from typing import (
|
||||||
|
|
||||||
|
|
||||||
def namespacify(value: Any) -> Any:
|
def namespacify(value: Any) -> Any:
|
||||||
if isinstance(value, (Namespace, MutableNamespace)):
|
if isinstance(value, Namespace):
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, MutableMapping):
|
if isinstance(value, Mapping):
|
||||||
return MutableNamespace(value)
|
|
||||||
elif isinstance(value, Mapping):
|
|
||||||
return Namespace(value)
|
return Namespace(value)
|
||||||
elif isinstance(value, (str, ByteString)):
|
if isinstance(value, (str, ByteString)):
|
||||||
# Do not treat strings and bytestrings as normal sequences
|
# Do not treat strings and bytestrings as normal sequences
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, Sequence):
|
if isinstance(value, Sequence):
|
||||||
return list(map(namespacify, value))
|
return list(map(namespacify, value))
|
||||||
elif isinstance(value, Set):
|
if isinstance(value, Set):
|
||||||
return set(map(namespacify, value))
|
return set(map(namespacify, value))
|
||||||
elif isinstance(value, Iterable):
|
if isinstance(value, Iterable):
|
||||||
return map(namespacify, value)
|
return map(namespacify, value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class Namespace(Mapping):
|
class Namespace(MutableMapping):
|
||||||
|
|
||||||
def __init__(self, *args: Iterable, **kwargs: Any):
|
def __init__(self, *args: Iterable, **kwargs: Any):
|
||||||
for iterable in (*args, kwargs):
|
for iterable in (*args, kwargs):
|
||||||
|
@ -54,9 +52,6 @@ class Namespace(Mapping):
|
||||||
def copy(self) -> 'Namespace':
|
def copy(self) -> 'Namespace':
|
||||||
return self.__class__(self.__dict__)
|
return self.__class__(self.__dict__)
|
||||||
|
|
||||||
|
|
||||||
class MutableNamespace(Namespace, MutableMapping):
|
|
||||||
|
|
||||||
def __setitem__(self, name: Any, value: Any) -> None:
|
def __setitem__(self, name: Any, value: Any) -> None:
|
||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
from types import MappingProxyType
|
||||||
|
from typing import List, Set, Iterable, Iterator, Any
|
||||||
|
from unittest import TestCase
|
||||||
|
from objtools.collections import namespacify, Namespace
|
||||||
|
|
||||||
|
|
||||||
|
class TestNamespacify(TestCase):
|
||||||
|
|
||||||
|
def test_namespace(self) -> None:
|
||||||
|
ns: Namespace = Namespace(a='b')
|
||||||
|
self.assertIs(ns, namespacify(ns))
|
||||||
|
|
||||||
|
def test_mapping(self) -> None:
|
||||||
|
ns: Namespace = namespacify(MappingProxyType({'a': 'b', 'c': 'd'}))
|
||||||
|
self.assertIsInstance(ns, Namespace)
|
||||||
|
self.assertEqual(dict(ns), {'a': 'b', 'c': 'd'})
|
||||||
|
|
||||||
|
def test_str(self) -> None:
|
||||||
|
ns: str = namespacify('something')
|
||||||
|
self.assertEqual(ns, 'something')
|
||||||
|
|
||||||
|
def test_bytes(self) -> None:
|
||||||
|
ns: bytes = namespacify(b'something')
|
||||||
|
self.assertEqual(ns, b'something')
|
||||||
|
|
||||||
|
def test_sequence(self) -> None:
|
||||||
|
ns: List[Namespace] = namespacify([{'a': 'b'}, {'c': 'd'}])
|
||||||
|
self.assertIsInstance(ns, list)
|
||||||
|
self.assertTrue(all(isinstance(n, Namespace) for n in ns))
|
||||||
|
self.assertListEqual(list(map(dict, ns)), [{'a': 'b'}, {'c': 'd'}])
|
||||||
|
|
||||||
|
def test_set(self) -> None:
|
||||||
|
ns: Set[int] = namespacify({1, 2, 3, 4, 5})
|
||||||
|
self.assertSetEqual(ns, {1, 2, 3, 4, 5})
|
||||||
|
|
||||||
|
def test_iterable(self) -> None:
|
||||||
|
ns: Iterable[Namespace] = namespacify(
|
||||||
|
map(MappingProxyType, [{'a': 'b'}, {'c': 'd'}])
|
||||||
|
)
|
||||||
|
self.assertNotIsInstance(ns, list)
|
||||||
|
ns = list(ns)
|
||||||
|
self.assertTrue(all(isinstance(n, Namespace) for n in ns))
|
||||||
|
self.assertListEqual(list(map(dict, ns)), [{'a': 'b'}, {'c': 'd'}])
|
||||||
|
|
||||||
|
def test_any(self) -> None:
|
||||||
|
self.assertEqual(namespacify(42), 42)
|
||||||
|
self.assertEqual(namespacify(42.0), 42.0)
|
||||||
|
self.assertEqual(namespacify(True), True)
|
||||||
|
self.assertEqual(namespacify(namespacify), namespacify)
|
||||||
|
|
||||||
|
|
||||||
|
class TestNamespace(TestCase):
|
||||||
|
|
||||||
|
def test_init(self) -> None:
|
||||||
|
ns: Namespace = Namespace()
|
||||||
|
self.assertDictEqual(dict(ns), {})
|
||||||
|
ns = Namespace({'b': 3}, {'a': 4}, a=1, b=2)
|
||||||
|
self.assertDictEqual(dict(ns), {'a': 1, 'b': 2})
|
||||||
|
|
||||||
|
def test_getitem(self) -> None:
|
||||||
|
ns: Namespace = Namespace(a=1)
|
||||||
|
self.assertEqual(ns['a'], 1)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
ns['b']
|
||||||
|
|
||||||
|
def test_getattr(self) -> None:
|
||||||
|
ns: Any = Namespace(a=1)
|
||||||
|
self.assertEqual(getattr(ns, 'a'), 1)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
ns.b
|
||||||
|
|
||||||
|
def test_iter(self) -> None:
|
||||||
|
ns: Namespace = Namespace(a=1, b=2)
|
||||||
|
iterator: Iterator = iter(ns)
|
||||||
|
self.assertEqual(next(iterator), 'a')
|
||||||
|
self.assertEqual(next(iterator), 'b')
|
||||||
|
|
||||||
|
def test_len(self) -> None:
|
||||||
|
self.assertEqual(len(Namespace(a=1, b=2)), 2)
|
||||||
|
self.assertEqual(len(Namespace()), 0)
|
||||||
|
|
||||||
|
def test_repr(self) -> None:
|
||||||
|
self.assertEqual(repr(Namespace()), 'Namespace({})')
|
||||||
|
self.assertEqual(repr(Namespace(a=1)), "Namespace({'a': 1})")
|
||||||
|
|
||||||
|
def test_str(self) -> None:
|
||||||
|
self.assertEqual(str(Namespace()), '{}')
|
||||||
|
self.assertEqual(str(Namespace(a=1)), "{'a': 1}")
|
||||||
|
|
||||||
|
def test_copy(self) -> None:
|
||||||
|
ns: Namespace = Namespace(a=1, b=2)
|
||||||
|
self.assertEqual(ns.copy(), ns)
|
||||||
|
self.assertIsNot(ns.copy(), ns)
|
||||||
|
|
||||||
|
def test_set(self) -> None:
|
||||||
|
ns: Any = Namespace(a=4)
|
||||||
|
ns.a = 1
|
||||||
|
ns['b'] = 2
|
||||||
|
self.assertEqual(ns, Namespace(a=1, b=2))
|
||||||
|
|
||||||
|
def test_del(self) -> None:
|
||||||
|
ns: Any = Namespace(a=1, b=2)
|
||||||
|
del ns.a
|
||||||
|
self.assertEqual(ns, Namespace(b=2))
|
||||||
|
del ns['b']
|
||||||
|
self.assertEqual(ns, Namespace())
|
||||||
|
|
||||||
|
def test_del_not_found(self) -> None:
|
||||||
|
ns: Any = Namespace(a=1, b=2)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del ns.c
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
del ns['c']
|
|
@ -0,0 +1,63 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import patch
|
||||||
|
from objtools.registry import ClassRegistry
|
||||||
|
|
||||||
|
|
||||||
|
class TestRegistry(TestCase):
|
||||||
|
|
||||||
|
def test_register(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
registry.register('lol', str)
|
||||||
|
self.assertDictEqual(registry, {'lol': str})
|
||||||
|
|
||||||
|
def test_unregister(self) -> None:
|
||||||
|
registry = ClassRegistry({'lol': str})
|
||||||
|
registry.unregister('lol')
|
||||||
|
self.assertDictEqual(registry, {})
|
||||||
|
|
||||||
|
def test_check_key(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
with patch.object(registry, 'check_key') as mock:
|
||||||
|
mock.side_effect = KeyError('something')
|
||||||
|
with self.assertRaises(KeyError, msg='something'):
|
||||||
|
registry.register('lol', str)
|
||||||
|
|
||||||
|
mock.side_effect = AssertionError('something')
|
||||||
|
with self.assertRaises(KeyError, msg='something'):
|
||||||
|
registry.register('lol', str)
|
||||||
|
|
||||||
|
def test_check_value(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
with patch.object(registry, 'check_value') as mock:
|
||||||
|
mock.side_effect = ValueError('something')
|
||||||
|
with self.assertRaises(ValueError, msg='something'):
|
||||||
|
registry.register('lol', str)
|
||||||
|
|
||||||
|
mock.side_effect = AssertionError('something')
|
||||||
|
with self.assertRaises(ValueError, msg='something'):
|
||||||
|
registry.register('lol', str)
|
||||||
|
|
||||||
|
def test_metaclass(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
|
||||||
|
class Thing(metaclass=registry.metaclass): # type: ignore
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertDictEqual(registry, {'Thing': Thing})
|
||||||
|
|
||||||
|
def test_metaclass_no_register(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
|
||||||
|
class Thing(metaclass=registry.metaclass, # type: ignore
|
||||||
|
register=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertDictEqual(registry, {})
|
||||||
|
|
||||||
|
def test_metaclass_key(self) -> None:
|
||||||
|
registry = ClassRegistry()
|
||||||
|
|
||||||
|
class Thing(metaclass=registry.metaclass, key='foo'): # type: ignore
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertDictEqual(registry, {'foo': Thing})
|
Loading…
Reference in New Issue