from collections import OrderedDict from unittest import main, TestCase class WorkingSimpleLRUCache(OrderedDict): def __init__(self, size): super().__init__() self.size = size def __getitem__(self, item): value = super().__getitem__(item) del self[item] self[item] = value return value def __setitem__(self, key, value): while key not in self and len(self) >= self.size: self.popitem(last=False) super().__setitem__(key, value) self.move_to_end(key) class FailingSimpleLRUCache(OrderedDict): def __init__(self, size): super().__init__() self.size = size def __getitem__(self, item): value = super().__getitem__(item) self.move_to_end(item) return value def __setitem__(self, key, value): while key not in self and len(self) >= self.size: self.popitem(last=False) super().__setitem__(key, value) self.move_to_end(key) class BaseTestCase: def test_add_after_full(self): c = self.cls(2) c['t1'] = 1 c['t2'] = 2 c['t3'] = 3 self.assertEqual(list(c), ['t2', 't3']) def test_popitem(self): c = self.cls(3) for i in range(1, 4): c[i] = i self.assertEqual(c.popitem(last=False), (1, 1)) self.assertEqual(c.popitem(last=True), (3, 3)) def test_change_order_on_get(self): c = self.cls(3) for i in range(1, 4): c[i] = i self.assertEqual(list(c), list(range(1, 4))) self.assertEqual(c[2], 2) self.assertEqual(list(c), [1, 3, 2]) class WorkingTestCase(BaseTestCase, TestCase): cls = WorkingSimpleLRUCache class FailingTestCase(BaseTestCase, TestCase): cls = FailingSimpleLRUCache if __name__ == '__main__': main()