Skip to content

Commit

Permalink
A Patcher class
Browse files Browse the repository at this point in the history
  • Loading branch information
regebro committed Feb 21, 2019
1 parent 084f26e commit 9f3d4e2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 9 deletions.
14 changes: 7 additions & 7 deletions tests/test_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import unittest

from lxml import etree
from xmldiff import diff, formatting, main, actions
from xmldiff import formatting, main, actions

from .testing import generate_filebased_cases

Expand Down Expand Up @@ -298,7 +298,7 @@ def test_update_text_in(self):

left = u'<document><node>This is a bit of text, right' + END
action = actions.UpdateTextIn('/document/node',
'Also a bit of text, rick')
'Also a bit of text, rick')
expected = START + u'><diff:delete>This is</diff:delete><diff:insert>'\
u'Also</diff:insert> a bit of text, ri<diff:delete>ght'\
u'</diff:delete><diff:insert>ck</diff:insert>' + END
Expand All @@ -316,7 +316,7 @@ def test_update_text_after_1(self):
def test_update_text_after_2(self):
left = u'<document><node/>This is a bit of text, right</document>'
action = actions.UpdateTextAfter('/document/node',
'Also a bit of text, rick')
'Also a bit of text, rick')
expected = START + u'/><diff:delete>This is</diff:delete>'\
u'<diff:insert>Also</diff:insert> a bit of text, ri<diff:delete>'\
u'ght</diff:delete><diff:insert>ck</diff:insert></document>'
Expand Down Expand Up @@ -396,7 +396,7 @@ def test_update_text_in(self):
self._format_test(action, expected)

action = actions.UpdateTextIn('/document/node',
'Also a bit of text, "rick"')
'Also a bit of text, "rick"')
expected = '[update-text, /document/node, '\
u'"Also a bit of text, \\"rick\\""]'
self._format_test(action, expected)
Expand All @@ -408,7 +408,7 @@ def test_update_text_after_1(self):

def test_update_text_after_2(self):
action = actions.UpdateTextAfter('/document/node',
'Also a bit of text, rick')
'Also a bit of text, rick')
expected = '[update-text-after, /document/node, '\
u'"Also a bit of text, rick"]'
self._format_test(action, expected)
Expand Down Expand Up @@ -476,7 +476,7 @@ def test_update_text_in(self):
self._format_test(action, expected)

action = actions.UpdateTextIn('/document/node',
'Also a bit of text, "rick"')
'Also a bit of text, "rick"')
expected = '[update, /document/node/text()[1], '\
u'"Also a bit of text, \\"rick\\""]'
self._format_test(action, expected)
Expand All @@ -488,7 +488,7 @@ def test_update_text_after_1(self):

def test_update_text_after_2(self):
action = actions.UpdateTextAfter('/document/node',
'Also a bit of text, rick')
'Also a bit of text, rick')
expected = '[update, /document/node/text()[2], '\
u'"Also a bit of text, rick"]'
self._format_test(action, expected)
Expand Down
4 changes: 2 additions & 2 deletions xmldiff/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ def diff(self, left=None, right=None):
pos = self.find_pos(rnode)
# (ii)
if rnode.tag is etree.Comment:
yield actions.InsertComment(utils.getpath(ltarget, ltree), pos,
rnode.text)
yield actions.InsertComment(
utils.getpath(ltarget, ltree), pos, rnode.text)
lnode = etree.Comment(rnode.text)
else:
yield actions.InsertNode(utils.getpath(ltarget, ltree),
Expand Down
59 changes: 59 additions & 0 deletions xmldiff/patch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from lxml import etree


class Patcher(object):

def handle_action(self, action, tree):
action_type = type(action)
method = getattr(self, '_handle_' + action_type.__name__)
method(action, tree)

def _handle_DeleteNode(self, action, tree):
node = tree.xpath(action.node)[0]
node.getparent().remove(node)

def _handle_InsertNode(self, action, tree):
target = tree.xpath(action.target)[0]
node = target.makeelement(action.tag)
target.insert(action.position, node)

def _handle_RenameNode(self, action, tree):
tree.xpath(action.node)[0].tag = action.tag

def _handle_MoveNode(self, action, tree):
node = tree.xpath(action.node)[0]
node.getparent().remove(node)
target = tree.xpath(action.target)[0]
target.insert(action.position, node)

def _handle_UpdateTextIn(self, action, tree):
tree.xpath(action.node)[0].text = action.text

def _handle_UpdateTextAfter(self, action, tree):
tree.xpath(action.node)[0].tail = action.text

def _handle_UpdateAttrib(self, action, tree):
node = tree.xpath(action.node)[0]
# This should not be used to insert new attributes.
assert action.name in node.attrib
node.attrib[action.name] = action.value

def _handle_DeleteAttrib(self, action, tree):
del tree.xpath(action.node)[0].attrib[action.name]

def _handle_InsertAttrib(self, action, tree):
node = tree.xpath(action.node)[0]
# This should not be used to update existing attributes.
assert action.name not in node.attrib
node.attrib[action.name] = action.value

def _handle_RenameAttrib(self, action, tree):
node = tree.xpath(action.node)[0]
assert action.oldname in node.attrib
assert action.newname not in node.attrib
node.attrib[action.newname] = node.attrib[action.oldname]
del node.attrib[action.oldname]

def _handle_InsertComment(self, action, tree):
target = tree.xpath(action.target)[0]
target.insert(action.position, etree.Comment(action.text))

0 comments on commit 9f3d4e2

Please sign in to comment.