diff options
author | Morgan Fainberg <morgan.fainberg@gmail.com> | 2016-06-03 16:51:38 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-06-21 11:11:21 -0400 |
commit | 656df0ba9df3c37fa5e61e6b7918da03746f9f39 (patch) | |
tree | 37c5955ae6788ea4999a59da2faf1fca715c546c /tests | |
parent | c185db8749eb140b926c545bf7153fe273f8925f (diff) | |
download | dogpile-cache-656df0ba9df3c37fa5e61e6b7918da03746f9f39.tar.gz |
Add a key-word-arg aware cache-key generator
Add in a key-word-arg cache key generator that may be optionally
used. This generator will generate a key that mirrors closely to
the original key generator. The key difference is that it will
flatten all arguments down to just the values ordered alphabetically
based on the argument name. This order will be used to ensure that
regardless of the order that the keys are passed (positional,
key-word, or out-of-order key-word) the cache key ends up being
the same.
This was not made the default keygenerator to avoid reverse
incompatibilities with developers that are relying on stable
cache-key generation (e.g. storing data via the memcache-like
interface to a non-volitile backend).
Fixes: #43
Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com>
Change-Id: I86c9d5e9c611090d5a84d8a746486a0b6c80039a
Pull-request: https://bitbucket.org/zzzeek/dogpile.cache/pull-requests/46
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cache/test_decorator.py | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/cache/test_decorator.py b/tests/cache/test_decorator.py index d034986..01d7bf4 100644 --- a/tests/cache/test_decorator.py +++ b/tests/cache/test_decorator.py @@ -199,6 +199,75 @@ class KeyGenerationTest(TestCase): return fn return decorate, canary + def _kwarg_keygen_decorator(self, namespace=None, **kw): + canary = [] + + def decorate(fn): + canary.append( + util.kwarg_function_key_generator(namespace, fn, **kw)) + return fn + return decorate, canary + + def test_default_keygen_kwargs_raises_value_error(self): + decorate, canary = self._keygen_decorator() + + @decorate + def one(a, b): + pass + + gen = canary[0] + self.assertRaises(ValueError, gen, 1, b=2) + + def test_kwarg_kegen_keygen_fn(self): + decorate, canary = self._kwarg_keygen_decorator() + + @decorate + def one(a, b): + pass + gen = canary[0] + + result_key = "tests.cache.test_decorator:one|1 2" + + eq_(gen(1, 2), result_key) + eq_(gen(1, b=2), result_key) + eq_(gen(a=1, b=2), result_key) + eq_(gen(b=2, a=1), result_key) + + def test_kwarg_kegen_keygen_fn_with_defaults_and_positional(self): + decorate, canary = self._kwarg_keygen_decorator() + + @decorate + def one(a, b=None): + pass + gen = canary[0] + + result_key = "tests.cache.test_decorator:one|1 2" + + eq_(gen(1, 2), result_key) + eq_(gen(1, b=2), result_key) + eq_(gen(a=1, b=2), result_key) + eq_(gen(b=2, a=1), result_key) + eq_(gen(a=1), "tests.cache.test_decorator:one|1 None") + + def test_kwarg_kegen_keygen_fn_all_defaults(self): + decorate, canary = self._kwarg_keygen_decorator() + + @decorate + def one(a=True, b=None): + pass + gen = canary[0] + + result_key = "tests.cache.test_decorator:one|1 2" + + eq_(gen(1, 2), result_key) + eq_(gen(1, b=2), result_key) + eq_(gen(a=1, b=2), result_key) + eq_(gen(b=2, a=1), result_key) + eq_(gen(a=1), "tests.cache.test_decorator:one|1 None") + eq_(gen(1), "tests.cache.test_decorator:one|1 None") + eq_(gen(), "tests.cache.test_decorator:one|True None") + eq_(gen(b=2), "tests.cache.test_decorator:one|True 2") + def test_keygen_fn(self): decorate, canary = self._keygen_decorator() @@ -234,6 +303,17 @@ class KeyGenerationTest(TestCase): eq_(gen(1, 2), "tests.cache.test_decorator:one|mynamespace|1 2") eq_(gen(None, 5), "tests.cache.test_decorator:one|mynamespace|None 5") + def test_kwarg_keygen_fn_namespace(self): + decorate, canary = self._kwarg_keygen_decorator("mynamespace") + + @decorate + def one(a, b): + pass + gen = canary[0] + + eq_(gen(1, 2), "tests.cache.test_decorator:one|mynamespace|1 2") + eq_(gen(None, 5), "tests.cache.test_decorator:one|mynamespace|None 5") + def test_key_isnt_unicode_bydefault(self): decorate, canary = self._keygen_decorator("mynamespace") @@ -244,6 +324,17 @@ class KeyGenerationTest(TestCase): assert isinstance(gen('foo'), str) + def test_kwarg_kwgen_key_isnt_unicode_bydefault(self): + decorate, canary = self._kwarg_keygen_decorator("mynamespace") + + @decorate + def one(a, b): + pass + gen = canary[0] + + assert isinstance(gen('foo'), str) + + def test_unicode_key(self): decorate, canary = self._keygen_decorator("mynamespace", to_str=compat.text_type) @@ -257,6 +348,20 @@ class KeyGenerationTest(TestCase): compat.ue("tests.cache.test_decorator:" "one|mynamespace|m\xe9il dr\xf4le")) + def test_unicode_key_kwarg_generator(self): + decorate, canary = self._kwarg_keygen_decorator( + "mynamespace", + to_str=compat.text_type) + + @decorate + def one(a, b): + pass + gen = canary[0] + + eq_(gen(compat.u('méil'), compat.u('drôle')), + compat.ue("tests.cache.test_decorator:" + "one|mynamespace|m\xe9il dr\xf4le")) + def test_unicode_key_multi(self): decorate, canary = self._multi_keygen_decorator( "mynamespace", @@ -291,6 +396,23 @@ class KeyGenerationTest(TestCase): "tests.cache.test_decorator:" "one|mynamespace|m\xe9il dr\xf4le") + @requires_py3k + def test_unicode_key_by_default_kwarg_generator(self): + decorate, canary = self._kwarg_keygen_decorator( + "mynamespace", + to_str=compat.text_type) + + @decorate + def one(a, b): + pass + gen = canary[0] + + assert isinstance(gen('méil'), str) + + eq_(gen('méil', 'drôle'), + "tests.cache.test_decorator:" + "one|mynamespace|m\xe9il dr\xf4le") + class CacheDecoratorTest(_GenericBackendFixture, TestCase): backend = "mock" |