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():

Reply via email to