import pytest

from mock import patch

from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache
from data.cache.cache_key import CacheKey


class MockClient(object):
    def __init__(self, server, **kwargs):
        self.data = {}

    def get(self, key, default=None):
        return self.data.get(key, default)

    def set(self, key, value, expire=None):
        self.data[key] = value


@pytest.mark.parametrize("cache_type", [(NoopDataModelCache), (InMemoryDataModelCache),])
def test_caching(cache_type):
    key = CacheKey("foo", "60m")
    cache = cache_type()

    # Perform two retrievals, and make sure both return.
    assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}
    assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}


def test_memcache():
    key = CacheKey("foo", "60m")
    with patch("data.cache.impl.Client", MockClient):
        cache = MemcachedModelCache(("127.0.0.1", "-1"))
        assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}
        assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}


def test_memcache_should_cache():
    key = CacheKey("foo", None)

    def sc(value):
        return value["a"] != 1234

    with patch("data.cache.impl.Client", MockClient):
        cache = MemcachedModelCache(("127.0.0.1", "-1"))
        assert cache.retrieve(key, lambda: {"a": 1234}, should_cache=sc) == {"a": 1234}

        # Ensure not cached since it was `1234`.
        assert cache._get_client().get(key.key) is None

        # Ensure cached.
        assert cache.retrieve(key, lambda: {"a": 2345}, should_cache=sc) == {"a": 2345}
        assert cache._get_client().get(key.key) is not None
        assert cache.retrieve(key, lambda: {"a": 2345}, should_cache=sc) == {"a": 2345}

[((20, 1, 20, 89), 'pytest.mark.parametrize', 'pytest.mark.parametrize', ({(20, 25, 20, 37): '"""cache_type"""', (20, 39, 20, 88): '[NoopDataModelCache, InMemoryDataModelCache]'}, {}), "('cache_type', [NoopDataModelCache,\n    InMemoryDataModelCache])", False, 'import pytest\n'), ((22, 10, 22, 32), 'data.cache.cache_key.CacheKey', 'CacheKey', ({(22, 19, 22, 24): '"""foo"""', (22, 26, 22, 31): '"""60m"""'}, {}), "('foo', '60m')", False, 'from data.cache.cache_key import CacheKey\n'), ((31, 10, 31, 32), 'data.cache.cache_key.CacheKey', 'CacheKey', ({(31, 19, 31, 24): '"""foo"""', (31, 26, 31, 31): '"""60m"""'}, {}), "('foo', '60m')", False, 'from data.cache.cache_key import CacheKey\n'), ((39, 10, 39, 31), 'data.cache.cache_key.CacheKey', 'CacheKey', ({(39, 19, 39, 24): '"""foo"""', (39, 26, 39, 30): 'None'}, {}), "('foo', None)", False, 'from data.cache.cache_key import CacheKey\n'), ((32, 9, 32, 52), 'mock.patch', 'patch', ({(32, 15, 32, 39): '"""data.cache.impl.Client"""', (32, 41, 32, 51): 'MockClient'}, {}), "('data.cache.impl.Client', MockClient)", False, 'from mock import patch\n'), ((33, 16, 33, 56), 'data.cache.MemcachedModelCache', 'MemcachedModelCache', ({(33, 36, 33, 55): "('127.0.0.1', '-1')"}, {}), "(('127.0.0.1', '-1'))", False, 'from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache\n'), ((44, 9, 44, 52), 'mock.patch', 'patch', ({(44, 15, 44, 39): '"""data.cache.impl.Client"""', (44, 41, 44, 51): 'MockClient'}, {}), "('data.cache.impl.Client', MockClient)", False, 'from mock import patch\n'), ((45, 16, 45, 56), 'data.cache.MemcachedModelCache', 'MemcachedModelCache', ({(45, 36, 45, 55): "('127.0.0.1', '-1')"}, {}), "(('127.0.0.1', '-1'))", False, 'from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache\n')]