def test__removals_nor_changes__returns_no_items__when_item_is_put_back(): d = IdMapper({"a": 1}) del d["a"] d["a"] = 1 assert [(k, v) for k, v in d.removals()] == [] assert [(k, v) for k, v in d.additions()] == [] assert [(k, v) for k, v in d.changes()] == []
def test__changes__returns_item__when_it_is_first_deleted_and_then_changed(): d = IdMapper({"a": 1}) del d["a"] d["a"] = 2 assert [(k, v) for k, v in d.removals()] == [] assert [(k, v) for k, v in d.additions()] == [] assert [(k, v) for k, v in d.changes()] == [("a", 2)]
def __init__(self, respa, remote, respa_memento=None, remote_memento=None, id_mapper=None, respa_change_keys={}, remote_change_keys={}, sync_actions=None): self.__respa = ChangeKeyWrapper(respa, respa_change_keys) self.__remote = ChangeKeyWrapper(remote, remote_change_keys) self.__id_map = IdMapper() if not id_mapper else id_mapper self.__respa_memento = respa_memento self.__remote_memento = remote_memento if sync_actions is not None: self._sync_actions = sync_actions else: self._sync_actions = reservationSyncActions
def test_sync_ignores_item_in_respa__when_change_key_matches(): # Arrange source1 = MemoryRepository() source2 = MemoryRepository() id1, change_key1 = source1.create_item("blaah1") id2, change_key2 = source2.create_item("blaah2") id_mapper = IdMapper({id1: id2}) sync = ReservationSync(respa=source1, remote=source2, respa_change_keys={id1: change_key1}, remote_change_keys={id2: change_key2}, id_mapper=id_mapper) # Act sync.sync_all() # Assert assert len(source1.get_items()) == 1, str(source1.get_items()) assert len(source2.get_items()) == 1, str(source2.get_items()) assert sorted(map(lambda v: v[1], source1.get_items())) == ["blaah1"] assert sorted(map(lambda v: v[1], source2.get_items())) == ["blaah2"]
class ReservationSync: def __init__(self, respa, remote, respa_memento=None, remote_memento=None, id_mapper=None, respa_change_keys={}, remote_change_keys={}, sync_actions=None): self.__respa = ChangeKeyWrapper(respa, respa_change_keys) self.__remote = ChangeKeyWrapper(remote, remote_change_keys) self.__id_map = IdMapper() if not id_mapper else id_mapper self.__respa_memento = respa_memento self.__remote_memento = remote_memento if sync_actions is not None: self._sync_actions = sync_actions else: self._sync_actions = reservationSyncActions def sync(self, respa_statuses, remote_statuses): respa_ids = [i for i in respa_statuses.keys()] remote_ids = [i for i in remote_statuses.keys()] respa_statuses, _ = self.__respa.get_changes_by_ids(respa_ids, self.__respa_memento) remote_statuses, _ = self.__remote.get_changes_by_ids(remote_ids, self.__remote_memento) self._sync(respa_statuses, remote_statuses) def _sync(self, respa_statuses, remote_statuses): def build_status_pair(respa_id, remote_id): respa_state = respa_statuses.get(respa_id, None) remote_state = remote_statuses.get(remote_id, None) respa_item = (respa_id, respa_state) if respa_id and respa_state else None remote_item = (remote_id, remote_state) if remote_id and remote_state else None return respa_item, remote_item def missing_ids(ids, other_ids, mapper): mapped_ids = [mapper.get(i, None) for i in ids] return [i for i in mapped_ids if i is not None and i not in other_ids] ids_missing_from_remote = missing_ids(respa_statuses.keys(), remote_statuses.keys(), self.__id_map) missing_changes_from_remote, _ = self.__remote.get_changes_by_ids(ids_missing_from_remote, self.__remote_memento) remote_statuses.update(missing_changes_from_remote) ids_missing_from_respa = missing_ids(remote_statuses.keys(), respa_statuses.keys(), self.__id_map.reverse) missing_changes_from_respa, _ = self.__respa.get_changes_by_ids(ids_missing_from_respa, self.__respa_memento) respa_statuses.update(missing_changes_from_respa) changes = set() for respa_id in respa_statuses: remote_id = self.__id_map.get(respa_id, None) changes.add(build_status_pair(respa_id, remote_id)) for remote_id in remote_statuses: respa_id = self.__id_map.reverse.get(remote_id, None) changes.add(build_status_pair(respa_id, remote_id)) ops = SyncOperations(changes, self._sync_actions).get_sync_operations() visitor = OpVisitor(self.__respa, self.__remote, self.__id_map) for op in ops: op.accept(visitor) def sync_all(self): respa_statuses, memento_respa = self.__respa.get_changes(self.__respa_memento) remote_statuses, memento_remote = self.__remote.get_changes(self.__remote_memento) self._sync(respa_statuses, remote_statuses) self.__respa_memento = memento_respa self.__remote_memento = memento_remote def respa_memento(self): return self.__respa_memento def remote_memento(self): return self.__remote_memento def respa_change_keys(self): return self.__respa.change_keys() def remote_change_keys(self): return self.__remote.change_keys()
def test__removals__returns_no_items__when_added_item_is_added_and_removed(): d = IdMapper() d["a"] = 1 del d["a"] assert [(k, v) for k, v in d.removals()] == [] assert [(k, v) for k, v in d.additions()] == []
def test__changes__returns_none__when_value_has_not_changed(): d = IdMapper({"b": 2}) d["b"] = 2 assert [(k, v) for k, v in d.changes()] == []
def test__changes__returns_changed_items__when_changed_using_reverse_map(): d = IdMapper({"b": 2}) d.reverse[3] = "b" assert [(k, v) for k, v in d.changes()] == [("b", 3)]
def test__changes__returns_changed_items(): d = IdMapper({"b": 2}) d["b"] = 3 assert [(k, v) for k, v in d.changes()] == [("b", 3)]
def test__reverse_get__return_the_key__when_value_has_been_set(): d = IdMapper() d["a"] = 1 assert d.reverse[1] == "a"
def test__removals__return_items_removed__when_removed_using_reversed_map(): d = IdMapper({"b": 2}) del d.reverse[2] assert [(k, v) for k, v in d.removals()] == [("b", 2)]
def test__removals__return_items_removed(): d = IdMapper({"b": 2}) del d["b"] assert [(k, v) for k, v in d.removals()] == [("b", 2)]
def test__additions__return_items_added__when_changed_multiple_times(): d = IdMapper() d["a"] = 1 d["a"] = 2 d["a"] = 3 assert [(k, v) for k, v in d.additions()] == [("a", 3)]
def test__additions__return_items_added__when_added_using_reverse_map(): d = IdMapper() d.reverse[1] = "a" assert [(k, v) for k, v in d.additions()] == [("a", 1)]
def test__additions__return_items_added(): d = IdMapper() d["a"] = 1 assert [(k, v) for k, v in d.additions()] == [("a", 1)]
def test__reverse_get__raises_key_error__when_item_is_deleted(): d = IdMapper() d["a"] = 1 del d.reverse[1] with pytest.raises(KeyError): assert d.reverse["a"]