tobiko/tobiko/tests/unit/test_cached.py

277 lines
8.1 KiB
Python

# Copyright 2020 Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import
import typing # noqa
import tobiko
from tobiko.tests import unit
NOT_CALLED = object()
class TestCached(unit.TobikoUnitTest):
my_property = tobiko.cached(doc='some doc')
def test_init(self):
prop = type(self).my_property
self.assertIsNone(prop.fget)
self.assertIsNone(prop.fset)
self.assertIsNone(prop.fdel)
self.assertEqual('some doc', prop.__doc__)
self.assertTrue(prop.cached_id)
def test_get(self):
ex = self.assertRaises(AttributeError, lambda: self.my_property)
self.assertEqual("Cached property has no getter method", str(ex))
def test_set(self):
self.my_property = value = object()
self.assertIs(value, self.my_property)
def test_delete(self):
self.my_property = object()
del self.my_property
ex = self.assertRaises(AttributeError, lambda: self.my_property)
self.assertEqual("Cached property has no getter method", str(ex))
class TestCachedWithGetter(unit.TobikoUnitTest):
@tobiko.cached
def my_property(self):
return object()
def test_init(self):
# pylint: disable=no-member
prop = type(self).my_property
assert isinstance(prop, tobiko.CachedProperty)
self.assertTrue(callable(prop.fget))
self.assertIsNone(prop.fset)
self.assertIsNone(prop.fdel)
self.assertIs(prop.fget.__doc__, prop.__doc__)
self.assertTrue(prop.cached_id)
def test_get(self):
value = self.my_property
self.assertIs(value, self.my_property)
def test_set(self):
self.my_property = value = object()
self.assertIs(value, self.my_property)
def test_delete(self):
self.my_property = value = object()
del self.my_property
self.assertIsNot(value, self.my_property)
class TestCachedWithSetter(unit.TobikoUnitTest):
_set_value = None
def set_my_property(self, value):
self._set_value = value
my_property = tobiko.cached(fset=set_my_property)
def test_init(self):
prop = type(self).my_property
self.assertIsNone(prop.fget)
self.assertIs(type(self).set_my_property, prop.fset)
self.assertIsNone(prop.fdel)
self.assertIsNone(prop.__doc__)
self.assertTrue(prop.cached_id)
def test_get(self):
self.assertFalse(hasattr(self, 'my_property'))
self.assertIsNone(self._set_value)
def test_set(self):
self.my_property = value = object()
self.assertIs(value, self.my_property)
self.assertIs(value, self._set_value)
def test_delete(self):
self.my_property = object()
del self.my_property
self.assertFalse(hasattr(self, 'my_property'))
class TestCachedWithDeleter(unit.TobikoUnitTest):
_delete_value = None
def delete_my_property(self):
self._delete_value = object()
my_property = tobiko.cached(fdel=delete_my_property)
def test_init(self):
prop = type(self).my_property
self.assertIsNone(prop.fget)
self.assertIsNone(prop.fset)
self.assertIs(type(self).delete_my_property, prop.fdel)
self.assertIsNone(prop.__doc__)
self.assertTrue(prop.cached_id)
def test_get(self):
self.assertFalse(hasattr(self, 'my_property'))
self.assertIsNone(self._delete_value)
def test_set(self):
self.my_property = value = object()
self.assertIs(value, self.my_property)
self.assertIsNone(self._delete_value)
def test_delete(self):
self.my_property = object()
del self.my_property
self.assertFalse(hasattr(self, 'my_property'))
self.assertIsNotNone(self._delete_value)
class TestCachedWithDoc(unit.TobikoUnitTest):
my_doc = 'some doc'
my_property = tobiko.cached(doc=my_doc)
@my_property.getter
def get_my_property(self):
return object()
def test_init(self):
prop = type(self).my_property
self.assertTrue(callable(prop.fget))
self.assertIsNone(prop.fset)
self.assertIsNone(prop.fdel)
self.assertIs(self.my_doc, prop.__doc__)
self.assertTrue(prop.cached_id)
class TestCachedWithCachedId(unit.TobikoUnitTest):
cached_id = 'my_cached_id'
my_property = tobiko.cached(cached_id=cached_id)
@my_property.getter
def get_my_property(self):
return object()
def test_init(self):
prop = type(self).my_property
self.assertTrue(callable(prop.fget))
self.assertIsNone(prop.fset)
self.assertIsNone(prop.fdel)
self.assertIsNone(prop.__doc__)
self.assertEqual(self.cached_id, prop.cached_id)
self.assertFalse(hasattr(self, 'my_cached_id'))
def test_get(self):
# pylint: disable=no-member
value = self.my_property
self.assertIs(value, self.my_property)
self.assertIs(value, self.my_cached_id)
def test_set(self):
# pylint: disable=no-member
self.my_property = value = object()
self.assertIs(value, self.my_property)
self.assertIs(value, self.my_cached_id)
def test_delete(self):
# pylint: disable=no-member
self.my_property = value = object()
del self.my_property
self.assertIsNot(value, self.my_property)
self.assertIsNot(value, self.my_cached_id)
class TestCachedWithDecorators(unit.TobikoUnitTest):
my_property = tobiko.cached()
getter_called = 0
@my_property.getter
def getter(self):
"""Getter documentation"""
self.getter_called += 1
return object()
setter_called = tuple() # type: typing.Tuple
@my_property.setter
def setter(self, value):
self.setter_called += (value,)
deleter_called = 0
@my_property.deleter
def deleter(self):
self.deleter_called += 1
def test_init(self):
# self.my_property method not called yet
prop = type(self).my_property
self.assertIs(type(self).getter, prop.fget)
self.assertIs(type(self).setter, prop.fset)
self.assertIs(type(self).deleter, prop.fdel)
self.assertIs(self.getter.__doc__, prop.__doc__)
self.assertTrue(prop.cached_id)
def test_get(self):
# my_property method is called
prop = type(self).my_property
value = self.my_property
self.assertEqual(1, self.getter_called)
self.assertIs(value, getattr(self, prop.cached_id))
self.assertEqual((value,), self.setter_called)
return value
def test_get_twice(self):
# my_property method is not called again
value1 = self.test_get()
value2 = self.test_get()
self.assertIs(value1, value2)
def test_set(self):
# property value is stored into the object
prop = type(self).my_property
self.my_property = value = object()
self.assertIs(value, self.my_property)
self.assertEqual(0, self.getter_called)
self.assertEqual(value, self.setter_called[-1])
self.assertIs(value, getattr(self, prop.cached_id))
return value
def test_set_twice(self):
# stored value is got after setting
value1 = self.test_set()
value2 = self.test_set()
self.assertIsNot(value1, value2)
def test_delete(self):
# deleting remove stored value
prop = type(self).my_property
value = self.test_set()
del self.my_property
self.assertFalse(hasattr(self, prop.cached_id))
self.assertIsNot(value, self.my_property)
self.assertEqual(1, self.deleter_called)