aboutsummaryrefslogtreecommitdiff
path: root/tests/test_method.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_method.py')
-rw-r--r--tests/test_method.py165
1 files changed, 165 insertions, 0 deletions
diff --git a/tests/test_method.py b/tests/test_method.py
new file mode 100644
index 0000000..b41dac0
--- /dev/null
+++ b/tests/test_method.py
@@ -0,0 +1,165 @@
+import operator
+import unittest
+
+from cachetools import LRUCache, cachedmethod, keys
+
+
+class Cached:
+ def __init__(self, cache, count=0):
+ self.cache = cache
+ self.count = count
+
+ @cachedmethod(operator.attrgetter("cache"))
+ def get(self, value):
+ count = self.count
+ self.count += 1
+ return count
+
+ @cachedmethod(operator.attrgetter("cache"), key=keys.typedkey)
+ def get_typed(self, value):
+ count = self.count
+ self.count += 1
+ return count
+
+ # https://github.com/tkem/cachetools/issues/107
+ def __hash__(self):
+ raise TypeError("unhashable type")
+
+
+class Locked:
+ def __init__(self, cache):
+ self.cache = cache
+ self.count = 0
+
+ @cachedmethod(operator.attrgetter("cache"), lock=lambda self: self)
+ def get(self, value):
+ return self.count
+
+ def __enter__(self):
+ self.count += 1
+
+ def __exit__(self, *exc):
+ pass
+
+
+class CachedMethodTest(unittest.TestCase):
+ def test_dict(self):
+ cached = Cached({})
+
+ self.assertEqual(cached.get(0), 0)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1.0), 1)
+ self.assertEqual(cached.get(1.0), 1)
+
+ cached.cache.clear()
+ self.assertEqual(cached.get(1), 2)
+
+ def test_typed_dict(self):
+ cached = Cached(LRUCache(maxsize=2))
+
+ self.assertEqual(cached.get_typed(0), 0)
+ self.assertEqual(cached.get_typed(1), 1)
+ self.assertEqual(cached.get_typed(1), 1)
+ self.assertEqual(cached.get_typed(1.0), 2)
+ self.assertEqual(cached.get_typed(1.0), 2)
+ self.assertEqual(cached.get_typed(0.0), 3)
+ self.assertEqual(cached.get_typed(0), 4)
+
+ def test_lru(self):
+ cached = Cached(LRUCache(maxsize=2))
+
+ self.assertEqual(cached.get(0), 0)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1.0), 1)
+ self.assertEqual(cached.get(1.0), 1)
+
+ cached.cache.clear()
+ self.assertEqual(cached.get(1), 2)
+
+ def test_typed_lru(self):
+ cached = Cached(LRUCache(maxsize=2))
+
+ self.assertEqual(cached.get_typed(0), 0)
+ self.assertEqual(cached.get_typed(1), 1)
+ self.assertEqual(cached.get_typed(1), 1)
+ self.assertEqual(cached.get_typed(1.0), 2)
+ self.assertEqual(cached.get_typed(1.0), 2)
+ self.assertEqual(cached.get_typed(0.0), 3)
+ self.assertEqual(cached.get_typed(0), 4)
+
+ def test_nospace(self):
+ cached = Cached(LRUCache(maxsize=0))
+
+ self.assertEqual(cached.get(0), 0)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1), 2)
+ self.assertEqual(cached.get(1.0), 3)
+ self.assertEqual(cached.get(1.0), 4)
+
+ def test_nocache(self):
+ cached = Cached(None)
+
+ self.assertEqual(cached.get(0), 0)
+ self.assertEqual(cached.get(1), 1)
+ self.assertEqual(cached.get(1), 2)
+ self.assertEqual(cached.get(1.0), 3)
+ self.assertEqual(cached.get(1.0), 4)
+
+ def test_weakref(self):
+ import weakref
+ import fractions
+ import gc
+
+ # in Python 3.4, `int` does not support weak references even
+ # when subclassed, but Fraction apparently does...
+ class Int(fractions.Fraction):
+ def __add__(self, other):
+ return Int(fractions.Fraction.__add__(self, other))
+
+ cached = Cached(weakref.WeakValueDictionary(), count=Int(0))
+
+ self.assertEqual(cached.get(0), 0)
+ gc.collect()
+ self.assertEqual(cached.get(0), 1)
+
+ ref = cached.get(1)
+ self.assertEqual(ref, 2)
+ self.assertEqual(cached.get(1), 2)
+ self.assertEqual(cached.get(1.0), 2)
+
+ ref = cached.get_typed(1)
+ self.assertEqual(ref, 3)
+ self.assertEqual(cached.get_typed(1), 3)
+ self.assertEqual(cached.get_typed(1.0), 4)
+
+ cached.cache.clear()
+ self.assertEqual(cached.get(1), 5)
+
+ def test_locked_dict(self):
+ cached = Locked({})
+
+ self.assertEqual(cached.get(0), 1)
+ self.assertEqual(cached.get(1), 3)
+ self.assertEqual(cached.get(1), 3)
+ self.assertEqual(cached.get(1.0), 3)
+ self.assertEqual(cached.get(2.0), 7)
+
+ def test_locked_nocache(self):
+ cached = Locked(None)
+
+ self.assertEqual(cached.get(0), 0)
+ self.assertEqual(cached.get(1), 0)
+ self.assertEqual(cached.get(1), 0)
+ self.assertEqual(cached.get(1.0), 0)
+ self.assertEqual(cached.get(1.0), 0)
+
+ def test_locked_nospace(self):
+ cached = Locked(LRUCache(maxsize=0))
+
+ self.assertEqual(cached.get(0), 1)
+ self.assertEqual(cached.get(1), 3)
+ self.assertEqual(cached.get(1), 5)
+ self.assertEqual(cached.get(1.0), 7)
+ self.assertEqual(cached.get(1.0), 9)