def setUp(self):
     """ initialize tests """
     self.storage = StorageMemory()
class TestFunctionCache(unittest.TestCase):
    """ test caches using a simple dictionary as the storage backend """

    _multiprocess_can_split_ = True #< let nose know that tests can run parallel
    
    
    def setUp(self):
        """ initialize tests """
        self.storage = StorageMemory()

    
    def test_simple(self):
        """ test a simple function """
        
        self.assertEqual(len(self.storage), 0)
        
        @cached(self.storage)
        def square(x, y):
            return x**2 + y
        
        a = square(2, 1)
        self.assertEqual(len(self.storage), 1)
        
        b = square(2, 1)
        self.assertEqual(a, b)
        self.assertEqual(len(self.storage), 1)        
        
        c = square(2, 2)
        self.assertNotEqual(a, c)
        self.assertEqual(len(self.storage), 2)        
        
        
    def test_clear(self):
        """ test clearing the cache """
        
        @cached(self.storage)
        def square(x):
            return x**2
        
        square(2)
        self.assertEqual(len(self.storage), 1)
        
        self.storage.clear()
        self.assertEqual(len(self.storage), 0)
        
        square(2)
        self.assertEqual(len(self.storage), 1)
        
        
    def test_clear_kwargs(self):
        """ test clearing the cache for particular keywords """
        
        @cached(self.storage)
        def square(x, e=2):
            if e is None:
                e = 1
            return x**e
        
        square(2, e=2)
        self.assertEqual(len(self.storage), 1)
        square(2, e=3)
        self.assertEqual(len(self.storage), 2)
        square(2, e=None)
        self.assertEqual(len(self.storage), 3)
        
        self.storage.clear(kwargs={'e': 2})
        self.assertEqual(len(self.storage), 2)
        
        square(2, e=3)
        self.assertEqual(len(self.storage), 2)        
        square(2, e=2)
        self.assertEqual(len(self.storage), 3)        
        
        
    def test_ignore_args(self):
        """ test ignoring some of the arguments """
        
        @cached(self.storage, ignore_kwargs=['y'])
        def square(x, y):
            return x**2
        
        a = square(2, y=1)
        self.assertEqual(len(self.storage), 1)
        
        b = square(2, y=2)
        self.assertEqual(a, b)
        self.assertEqual(len(self.storage), 1)        
        
        c = square(3, 2)
        self.assertNotEqual(a, c)
        self.assertEqual(len(self.storage), 2)       
        
        
    def test_object(self):
        """ test caching of objects """
         
        def square(x, e=2):
            return SimpleResult(x**e, e)
        
        square_cached = cached(self.storage)(square)
        
        a = square_cached(2, e=2)
        self.assertEqual(len(self.storage), 1)
        self.assertEqual(a, square(2, e=2))

        b = square_cached(2, e=3)
        self.assertEqual(len(self.storage), 2)
        self.assertEqual(b, square(2, e=3))

        c = square_cached(2, e=2)
        self.assertEqual(len(self.storage), 2)
        self.assertEqual(c, square(2, e=2))
        
        self.storage.clear(kwargs={'e': 2})
        self.assertEqual(len(self.storage), 1)
        
        self.assertEqual(b, square_cached(2, e=3))
        self.assertEqual(len(self.storage), 1)        

        self.assertEqual(a, square_cached(2, e=2))
        self.assertEqual(len(self.storage), 2)