Revision: 56fda067b1d0
Author: Pekka Klärck
Date: Sat Jun 30 13:13:45 2012
Log: XML library: Enhanced 'Elements Should (Be Equal/Match)' keywords
to show path to child when child are different.
http://code.google.com/p/robotframework/source/detail?r=56fda067b1d0
Modified:
/atest/testdata/standard_libraries/xml/elements_should_be_equal.txt
/atest/testdata/standard_libraries/xml/elements_should_match.txt
/src/robot/libraries/XML.py
/src/robot/utils/etreewrapper.py
=======================================
--- /atest/testdata/standard_libraries/xml/elements_should_be_equal.txt Sat
Jun 30 09:15:44 2012
+++ /atest/testdata/standard_libraries/xml/elements_should_be_equal.txt Sat
Jun 30 13:13:45 2012
@@ -10,28 +10,40 @@
<tag a="1" b="2"/>
<root>\n<tag>some\ntext</tag>tail text</root>
-Tag names are different
+Different tag names
<tag/> <täg/> Different tag name: tag != täg
-Different attribute values
+Different attributes
<tag a="1"/> <tag a="2"/> Different value for attribute 'a': 1 !=
2
<tag a="1" c="3"/> <tag b="1"/>
... Different attribute names: ['a', 'c'] != ['b']
-Texts are different
+Different texts
<tag>some text</tag> <tag>different</tag> Different text: some
text != different
<tag>some text</tag> <tag/> Different text: some text !=${SPACE}
-Different tails
- <root><tag/>tail</root> <root><tag/>wrong</root> Different tail
text: tail != wrong
- <root><tag/>tail</root> <root><tag/></root> Different tail text:
tail !=${SPACE}
+Different tail texts
+ <root><tag/>tail</root> <root><tag/>wrong</root>
+ ... Different tail text at 'root/tag': tail != wrong
+ <root><tag/>tail</root> <root><tag/></root>
+ ... Different tail text at 'root/tag': tail !=${SPACE}
Different number of children
<root><tag/><tag/></root> <root><tag/></root> Different number of
child elements: 2 != 1
-Differences in child
- <root><tag><child/></tag></root>
<root><different></different>tail</root>
- ... Different tag name: tag != different
+Differences in children
+ <root><tag/></root> <root><different/></root>
+ ... Different tag name at 'root/tag': tag != different
+ <a a="a"><b><c><d/></c></b></a> <a a="a"><b><c><wrong/></c></b></a>
+ ... Different tag name at 'a/b/c/d': d != wrong
+ <root><tag/></root> <root><tag a="1"/></root>
+ ... Different attribute names at 'root/tag': [] != ['a']
+ <a><b><c a="a" b="b"/></b></a> <a><b><c a="ä" b="b"></c></b></a>
+ ... Different value for attribute 'a' at 'a/b/c': a != ä
+ <root><tag/></root> <root><tag>text</tag></root>
+ ... Different text at 'root/tag': \ != text
+ <root><tag><c1/><c2/></tag></root> <root><tag/></root>
+ ... Different number of child elements at 'root/tag': 2 != 0
Normalize whitespace
[Template] NONE
=======================================
--- /atest/testdata/standard_libraries/xml/elements_should_match.txt Sat
Jun 30 09:15:44 2012
+++ /atest/testdata/standard_libraries/xml/elements_should_match.txt Sat
Jun 30 13:13:45 2012
@@ -9,25 +9,38 @@
<tag a="1" b="421"/> <tag a="?" b="4*"/>
<root>\n<tag>some\ntext</tag>tail text</root>
<root>\n<tag>some*</tag>tail??ex?</root>
-Tag names are different
+Different tag names
<tag/> <täg/> Different tag name: tag != täg
-Different attribute values
+Different attributes
<tag a="12"/> <tag a="?"/> Different value for
attribute 'a': '12' does not match '?'
<tag a="1" c="3"/> <tag a="?" b="?"/>
... Different attribute names: ['a', 'c'] != ['a', 'b']
-Texts are different
+Different texts
<tag>some text</tag> <tag>no match*</tag> Different text: 'some
text' does not match 'no match*'
<tag></tag> <tag>?*</tag> Different text: '' does not match '?*'
-Different tails
- <root><tag/>tail</root> <root><tag/>wrong*</root> Different tail
text: 'tail' does not match 'wrong*'
- <root><tag/></root> <root><tag/>?</root> Different tail text: ''
does not match '?'
-
-Differences in child
- <root><tag>content</tag></root> <root><tag>invalid*</tag></root>
- ... Different text: 'content' does not match 'invalid*'
+Different tail texts
+ <root><tag/>tail</root> <root><tag/>wrong*</root>
+ ... Different tail text at 'root/tag': 'tail' does not
match 'wrong*'
+ <root><tag/></root> <root><tag/>?</root>
+ ... Different tail text at 'root/tag': '' does not match '?'
+
+Differences in children
+ <root><tag/></root> <root><different/></root>
+ ... Different tag name at 'root/tag': tag != different
+ <a a="a"><b><c><d/></c></b></a> <a a="a"><b><c><wrong/></c></b></a>
+ ... Different tag name at 'a/b/c/d': d != wrong
+ <root><tag/></root> <root><tag a="1"/></root>
+ ... Different attribute names at 'root/tag': [] != ['a']
+ <a><b><c a="a" b="b"/></b></a> <a><b><c a="?" b="ä*"></c></b></a>
+ ... Different value for attribute 'b' at 'a/b/c': 'b' does not
match 'ä*'
+ <root><tag/></root> <root><tag>?</tag></root>
+ ... Different text at 'root/tag': '' does not match '?'
+ <root><tag><c1/><c2/></tag></root> <root><tag/></root>
+ ... Different number of child elements at 'root/tag': 2 != 0
+
Normalize whitespace
[Template] NONE
=======================================
--- /src/robot/libraries/XML.py Sat Jun 30 09:15:44 2012
+++ /src/robot/libraries/XML.py Sat Jun 30 13:13:45 2012
@@ -135,19 +135,27 @@
self._comparator = comparator
self._normalizer = normalizer
- def compare(self, actual, expected):
- self._compare_tags(actual, expected)
- self._compare_attributes(actual, expected)
- self._compare_texts(actual, expected)
- self._compare_tails(actual, expected)
- self._compare_children(actual, expected)
-
- def _compare_tags(self, actual, expected):
- should_be_equal(actual.tag, expected.tag, 'Different tag name')
-
- def _compare_texts(self, actual, expected):
- self._comparator(self._text(actual.text),
self._text(expected.text),
- 'Different text')
+ def compare(self, actual, expected, location=None):
+ self._compare_tags(actual, expected, location)
+ self._compare_attributes(actual, expected, location)
+ self._compare_texts(actual, expected, location)
+ self._compare_tails(actual, expected, location)
+ self._compare_children(actual, expected, location)
+
+ def _compare(self, actual, expected, message, location,
comparator=None):
+ if location:
+ message = "%s at '%s'" % (message, location)
+ if not comparator:
+ comparator = self._comparator
+ comparator(actual, expected, message)
+
+ def _compare_tags(self, actual, expected, location):
+ self._compare(actual.tag, expected.tag, 'Different tag name',
location,
+ should_be_equal)
+
+ def _compare_texts(self, actual, expected, location):
+ self._compare(self._text(actual.text), self._text(expected.text),
+ 'Different text', location)
def _text(self, text):
if not text:
@@ -156,19 +164,21 @@
return text
return self._normalizer(text)
- def _compare_attributes(self, actual, expected):
- should_be_equal(sorted(actual.attrib), sorted(expected.attrib),
- 'Different attribute names')
+ def _compare_attributes(self, actual, expected, location):
+ self._compare(sorted(actual.attrib), sorted(expected.attrib),
+ 'Different attribute names', location,
should_be_equal)
for key in actual.attrib:
- self._comparator(actual.attrib[key], expected.attrib[key],
- "Different value for attribute '%s'" % key)
-
- def _compare_tails(self, actual, expected):
- self._comparator(self._text(actual.tail),
self._text(expected.tail),
- 'Different tail text')
-
- def _compare_children(self, actual, expected):
- should_be_equal(len(actual), len(expected),
- 'Different number of child elements')
+ self._compare(actual.attrib[key], expected.attrib[key],
+ "Different value for attribute '%s'" % key,
location)
+
+ def _compare_tails(self, actual, expected, location):
+ self._compare(self._text(actual.tail), self._text(expected.tail),
+ 'Different tail text', location)
+
+ def _compare_children(self, actual, expected, location):
+ self._compare(len(actual), len(expected), 'Different number of
child elements',
+ location, should_be_equal)
+ if not location:
+ location = actual.tag
for act, exp in zip(actual, expected):
- self.compare(act, exp)
+ self.compare(act, exp, '%s/%s' % (location, act.tag))
=======================================
--- /src/robot/utils/etreewrapper.py Wed Jun 27 06:01:03 2012
+++ /src/robot/utils/etreewrapper.py Sat Jun 30 13:13:45 2012
@@ -65,7 +65,6 @@
self._opened.close()
if exc_type is None or exc_type is DataError:
return False
- raise DataError(exc_value) # TODO: this loses original traceback
def __str__(self):
if self._source_is_file_name():