2022-04-24 12:38:09 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# A library that provides a Python interface to the Telegram Bot API
|
|
|
|
# Copyright (C) 2015-2022
|
|
|
|
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Lesser Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Lesser Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Lesser Public License
|
|
|
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
from telegram.ext._utils.trackingdict import TrackingDict
|
|
|
|
|
|
|
|
|
2022-05-05 17:40:22 +02:00
|
|
|
@pytest.fixture(scope="function")
|
2022-04-24 12:38:09 +02:00
|
|
|
def td() -> TrackingDict:
|
|
|
|
td = TrackingDict()
|
|
|
|
td.update_no_track({1: 1})
|
|
|
|
return td
|
|
|
|
|
|
|
|
|
2022-05-05 17:40:22 +02:00
|
|
|
@pytest.fixture(scope="function")
|
2022-04-24 12:38:09 +02:00
|
|
|
def data() -> dict:
|
|
|
|
return {1: 1}
|
|
|
|
|
|
|
|
|
|
|
|
class TestTrackingDict:
|
|
|
|
def test_slot_behaviour(self, td, mro_slots):
|
|
|
|
for attr in td.__slots__:
|
2022-05-05 17:40:22 +02:00
|
|
|
assert getattr(td, attr, "err") != "err", f"got extra slot '{attr}'"
|
2022-04-24 12:38:09 +02:00
|
|
|
assert len(mro_slots(td)) == len(set(mro_slots(td))), "duplicate slot"
|
|
|
|
|
|
|
|
def test_representations(self, td, data):
|
|
|
|
assert repr(td) == repr(data)
|
|
|
|
assert str(td) == str(data)
|
|
|
|
|
|
|
|
def test_len(self, td, data):
|
|
|
|
assert len(td) == len(data)
|
|
|
|
|
|
|
|
def test_boolean(self, td, data):
|
|
|
|
assert bool(td) == bool(data)
|
|
|
|
assert bool(TrackingDict()) == bool({})
|
|
|
|
|
|
|
|
def test_equality(self, td, data):
|
|
|
|
assert td == data
|
|
|
|
assert data == td
|
|
|
|
assert td != TrackingDict()
|
|
|
|
assert TrackingDict() != td
|
|
|
|
td_2 = TrackingDict()
|
2022-05-05 17:40:22 +02:00
|
|
|
td_2["foo"] = 7
|
2022-04-24 12:38:09 +02:00
|
|
|
assert td != td_2
|
|
|
|
assert td_2 != td
|
|
|
|
assert td != 1
|
|
|
|
assert 1 != td
|
|
|
|
assert td != 5
|
|
|
|
assert 5 != td
|
|
|
|
|
|
|
|
def test_getitem(self, td):
|
|
|
|
assert td[1] == 1
|
|
|
|
assert not td.pop_accessed_write_items()
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
|
|
|
|
def test_setitem(self, td):
|
|
|
|
td[5] = 5
|
|
|
|
assert td[5] == 5
|
|
|
|
assert td.pop_accessed_write_items() == [(5, 5)]
|
|
|
|
td[5] = 7
|
|
|
|
assert td[5] == 7
|
|
|
|
assert td.pop_accessed_keys() == {5}
|
|
|
|
|
|
|
|
def test_delitem(self, td):
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
td[5] = 7
|
|
|
|
del td[1]
|
|
|
|
assert 1 not in td
|
|
|
|
assert td.pop_accessed_keys() == {1, 5}
|
|
|
|
td[1] = 7
|
|
|
|
td[5] = 7
|
|
|
|
assert td.pop_accessed_keys() == {1, 5}
|
|
|
|
del td[5]
|
|
|
|
assert 5 not in td
|
|
|
|
assert td.pop_accessed_write_items() == [(5, TrackingDict.DELETED)]
|
|
|
|
|
|
|
|
def test_update_no_track(self, td):
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
td.update_no_track({2: 2, 3: 3})
|
|
|
|
assert td == {1: 1, 2: 2, 3: 3}
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
|
|
|
|
def test_pop(self, td):
|
|
|
|
td.pop(1)
|
|
|
|
assert 1 not in td
|
|
|
|
assert td.pop_accessed_keys() == {1}
|
|
|
|
td[1] = 7
|
|
|
|
td[5] = 8
|
|
|
|
assert 1 in td
|
|
|
|
assert 5 in td
|
|
|
|
assert td.pop_accessed_keys() == {1, 5}
|
|
|
|
td.pop(5)
|
|
|
|
assert 5 not in td
|
|
|
|
assert td.pop_accessed_write_items() == [(5, TrackingDict.DELETED)]
|
|
|
|
|
|
|
|
with pytest.raises(KeyError):
|
|
|
|
td.pop(5)
|
|
|
|
|
|
|
|
assert td.pop(5, 8) == 8
|
|
|
|
assert 5 not in td
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
|
|
|
|
assert td.pop(5, 8) == 8
|
|
|
|
assert 5 not in td
|
|
|
|
assert not td.pop_accessed_write_items()
|
|
|
|
|
|
|
|
def test_popitem(self, td):
|
|
|
|
td.update_no_track({2: 2})
|
|
|
|
assert td.popitem() == (1, 1)
|
|
|
|
assert 1 not in td
|
|
|
|
assert td.pop_accessed_keys() == {1}
|
|
|
|
|
|
|
|
assert td.popitem() == (2, 2)
|
|
|
|
assert 2 not in td
|
|
|
|
assert not td
|
|
|
|
assert td.pop_accessed_write_items() == [(2, TrackingDict.DELETED)]
|
|
|
|
|
|
|
|
with pytest.raises(KeyError):
|
|
|
|
td.popitem()
|
|
|
|
|
|
|
|
def test_clear(self, td):
|
|
|
|
td.clear()
|
|
|
|
assert td == {}
|
|
|
|
assert td.pop_accessed_keys() == {1}
|
|
|
|
td[5] = 7
|
|
|
|
assert 5 in td
|
|
|
|
assert td.pop_accessed_keys() == {5}
|
|
|
|
td.clear()
|
|
|
|
assert td == {}
|
|
|
|
assert td.pop_accessed_write_items() == [(5, TrackingDict.DELETED)]
|
|
|
|
|
|
|
|
def test_set_default(self, td):
|
|
|
|
assert td.setdefault(1, 2) == 1
|
|
|
|
assert td[1] == 1
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
assert not td.pop_accessed_write_items()
|
|
|
|
|
|
|
|
assert td.setdefault(2, 3) == 3
|
|
|
|
assert td[2] == 3
|
|
|
|
assert td.pop_accessed_keys() == {2}
|
|
|
|
assert td.setdefault(3, 4) == 4
|
|
|
|
assert td[3] == 4
|
|
|
|
assert td.pop_accessed_write_items() == [(3, 4)]
|
|
|
|
|
|
|
|
def test_iter(self, td, data):
|
|
|
|
data.update({2: 2, 3: 3, 4: 4})
|
|
|
|
td.update_no_track({2: 2, 3: 3, 4: 4})
|
|
|
|
assert not td.pop_accessed_keys()
|
|
|
|
assert list(iter(td)) == list(iter(data))
|
|
|
|
|
|
|
|
def test_mark_as_accessed(self, td):
|
|
|
|
td[1] = 2
|
|
|
|
assert td.pop_accessed_keys() == {1}
|
|
|
|
assert td.pop_accessed_keys() == set()
|
|
|
|
td.mark_as_accessed(1)
|
|
|
|
assert td.pop_accessed_keys() == {1}
|