def test_move_attr(self): # The library currently only uses move attr for when attributes are # renamed: left = '<document><node attr="val">Text</node></document>' action = actions.RenameAttrib("/document/node", "attr", "bottr") expected = START + ' bottr="val" diff:rename-attr="attr:bottr"' ">Text" + END self._format_test(left, action, expected)
def update_node_attr(self, left, right): left_xpath = utils.getpath(left) # Update: Look for differences in attributes left_keys = set(left.attrib.keys()) right_keys = set(right.attrib.keys()) new_keys = right_keys.difference(left_keys) removed_keys = left_keys.difference(right_keys) common_keys = left_keys.intersection(right_keys) # We sort the attributes to get a consistent order in the edit script. # That's only so we can do testing in a reasonable way... for key in sorted(common_keys): if left.attrib[key] != right.attrib[key]: yield actions.UpdateAttrib(left_xpath, key, right.attrib[key]) left.attrib[key] = right.attrib[key] # Align: Not needed here, we don't care about the order of # attributes. # Move: Check if any of the new attributes have the same value # as the removed attributes. If they do, it's actually # a renaming, and a move is one action instead of remove + insert newattrmap = {v: k for (k, v) in right.attrib.items() if k in new_keys} for lk in sorted(removed_keys): value = left.attrib[lk] if value in newattrmap: rk = newattrmap[value] yield actions.RenameAttrib(left_xpath, lk, rk) # Remove from list of new attributes new_keys.remove(rk) # Delete used attribute from map of attributes del newattrmap[value] # Update left node left.attrib[rk] = value del left.attrib[lk] # Insert: Find new attributes for key in sorted(new_keys): yield actions.InsertAttrib(left_xpath, key, right.attrib[key]) left.attrib[key] = right.attrib[key] # Delete: remove removed attributes for key in sorted(removed_keys): if key not in left.attrib: # This was already moved continue yield actions.DeleteAttrib(left_xpath, key) del left.attrib[key]
def test_rename_attr(self): action = actions.RenameAttrib("/document/node", "attr", "bottr") expected = "[rename-attribute, /document/node, attr, bottr]" self._format_test(action, expected)
def _handle_rename_attribute(self, node, oldname, newname): return actions.RenameAttrib(node, oldname, newname)
def test_rename_attr(self): action = actions.RenameAttrib('/document/node', 'attr', 'bottr') expected = '[rename-attribute, /document/node, attr, bottr]' self._format_test(action, expected)