diff options
Diffstat (limited to '')
| -rw-r--r-- | tests/bot/utils/test_message_cache.py | 214 | 
1 files changed, 214 insertions, 0 deletions
| diff --git a/tests/bot/utils/test_message_cache.py b/tests/bot/utils/test_message_cache.py new file mode 100644 index 000000000..04bfd28d1 --- /dev/null +++ b/tests/bot/utils/test_message_cache.py @@ -0,0 +1,214 @@ +import unittest + +from bot.utils.message_cache import MessageCache +from tests.helpers import MockMessage + + +# noinspection SpellCheckingInspection +class TestMessageCache(unittest.TestCase): +    """Tests for the MessageCache class in the `bot.utils.caching` module.""" + +    def test_first_append_sets_the_first_value(self): +        """Test if the first append adds the message to the first cell.""" +        cache = MessageCache(maxlen=10) +        message = MockMessage() + +        cache.append(message) + +        self.assertEqual(cache[0], message) + +    def test_append_adds_in_the_right_order(self): +        """Test if two appends are added in the same order if newest_first is False, or in reverse order otherwise.""" +        messages = [MockMessage(), MockMessage()] + +        cache = MessageCache(maxlen=10, newest_first=False) +        for msg in messages: +            cache.append(msg) +        self.assertListEqual(messages, list(cache)) + +        cache = MessageCache(maxlen=10, newest_first=True) +        for msg in messages: +            cache.append(msg) +        self.assertListEqual(messages[::-1], list(cache)) + +    def test_appending_over_maxlen_removes_oldest(self): +        """Test if three appends to a 2-cell cache leave the two newest messages.""" +        cache = MessageCache(maxlen=2) +        messages = [MockMessage() for _ in range(3)] + +        for msg in messages: +            cache.append(msg) + +        self.assertListEqual(messages[1:], list(cache)) + +    def test_appending_over_maxlen_with_newest_first_removes_oldest(self): +        """Test if three appends to a 2-cell cache leave the two newest messages if newest_first is True.""" +        cache = MessageCache(maxlen=2, newest_first=True) +        messages = [MockMessage() for _ in range(3)] + +        for msg in messages: +            cache.append(msg) + +        self.assertListEqual(messages[:0:-1], list(cache)) + +    def test_pop_removes_from_the_end(self): +        """Test if a pop removes the right-most message.""" +        cache = MessageCache(maxlen=3) +        messages = [MockMessage() for _ in range(3)] + +        for msg in messages: +            cache.append(msg) +        msg = cache.pop() + +        self.assertEqual(msg, messages[-1]) +        self.assertListEqual(messages[:-1], list(cache)) + +    def test_popleft_removes_from_the_beginning(self): +        """Test if a popleft removes the left-most message.""" +        cache = MessageCache(maxlen=3) +        messages = [MockMessage() for _ in range(3)] + +        for msg in messages: +            cache.append(msg) +        msg = cache.popleft() + +        self.assertEqual(msg, messages[0]) +        self.assertListEqual(messages[1:], list(cache)) + +    def test_clear(self): +        """Test if a clear makes the cache empty.""" +        cache = MessageCache(maxlen=5) +        messages = [MockMessage() for _ in range(3)] + +        for msg in messages: +            cache.append(msg) +        cache.clear() + +        self.assertListEqual(list(cache), []) +        self.assertEqual(len(cache), 0) + +    def test_get_message_returns_the_message(self): +        """Test if get_message returns the cached message.""" +        cache = MessageCache(maxlen=5) +        message = MockMessage(id=1234) + +        cache.append(message) + +        self.assertEqual(cache.get_message(1234), message) + +    def test_get_message_returns_none(self): +        """Test if get_message returns None for an ID of a non-cached message.""" +        cache = MessageCache(maxlen=5) +        message = MockMessage(id=1234) + +        cache.append(message) + +        self.assertIsNone(cache.get_message(4321)) + +    def test_update_replaces_old_element(self): +        """Test if an update replaced the old message with the same ID.""" +        cache = MessageCache(maxlen=5) +        message = MockMessage(id=1234) + +        cache.append(message) +        message = MockMessage(id=1234) +        cache.update(message) + +        self.assertIs(cache.get_message(1234), message) +        self.assertEqual(len(cache), 1) + +    def test_contains_returns_true_for_cached_message(self): +        """Test if contains returns True for an ID of a cached message.""" +        cache = MessageCache(maxlen=5) +        message = MockMessage(id=1234) + +        cache.append(message) + +        self.assertIn(1234, cache) + +    def test_contains_returns_false_for_non_cached_message(self): +        """Test if contains returns False for an ID of a non-cached message.""" +        cache = MessageCache(maxlen=5) +        message = MockMessage(id=1234) + +        cache.append(message) + +        self.assertNotIn(4321, cache) + +    def test_indexing(self): +        """Test if the cache returns the correct messages by index.""" +        cache = MessageCache(maxlen=5) +        messages = [MockMessage() for _ in range(5)] + +        for msg in messages: +            cache.append(msg) + +        for current_loop in range(-5, 5): +            with self.subTest(current_loop=current_loop): +                self.assertEqual(cache[current_loop], messages[current_loop]) + +    def test_bad_index_raises_index_error(self): +        """Test if the cache raises IndexError for invalid indices.""" +        cache = MessageCache(maxlen=5) +        messages = [MockMessage() for _ in range(3)] +        test_cases = (-10, -4, 3, 4, 5) + +        for msg in messages: +            cache.append(msg) + +        for current_loop in test_cases: +            with self.subTest(current_loop=current_loop): +                with self.assertRaises(IndexError): +                    cache[current_loop] + +    def test_slicing_with_unfilled_cache(self): +        """Test if slicing returns the correct messages if the cache is not yet fully filled.""" +        sizes = (5, 10, 55, 101) + +        slices = ( +            slice(None), slice(2, None), slice(None, 2), slice(None, None, 2), slice(None, None, 3), slice(-1, 2), +            slice(-1, 3000), slice(-3, -1), slice(-10, 3), slice(-10, 4, 2), slice(None, None, -1), slice(None, 3, -2), +            slice(None, None, -3), slice(-1, -10, -2), slice(-3, -7, -1) +        ) + +        for size in sizes: +            cache = MessageCache(maxlen=size) +            messages = [MockMessage() for _ in range(size // 3 * 2)] + +            for msg in messages: +                cache.append(msg) + +            for slice_ in slices: +                with self.subTest(current_loop=(size, slice_)): +                    self.assertListEqual(cache[slice_], messages[slice_]) + +    def test_slicing_with_overfilled_cache(self): +        """Test if slicing returns the correct messages if the cache was appended with more messages it can contain.""" +        sizes = (5, 10, 55, 101) + +        slices = ( +            slice(None), slice(2, None), slice(None, 2), slice(None, None, 2), slice(None, None, 3), slice(-1, 2), +            slice(-1, 3000), slice(-3, -1), slice(-10, 3), slice(-10, 4, 2), slice(None, None, -1), slice(None, 3, -2), +            slice(None, None, -3), slice(-1, -10, -2), slice(-3, -7, -1) +        ) + +        for size in sizes: +            cache = MessageCache(maxlen=size) +            messages = [MockMessage() for _ in range(size * 3 // 2)] + +            for msg in messages: +                cache.append(msg) +            messages = messages[size // 2:] + +            for slice_ in slices: +                with self.subTest(current_loop=(size, slice_)): +                    self.assertListEqual(cache[slice_], messages[slice_]) + +    def test_length(self): +        """Test if len returns the correct number of items in the cache.""" +        cache = MessageCache(maxlen=5) + +        for current_loop in range(10): +            with self.subTest(current_loop=current_loop): +                self.assertEqual(len(cache), min(current_loop, 5)) +                cache.append(MockMessage()) | 
