diff --git a/src/jcl/jabber/command.py b/src/jcl/jabber/command.py
index 49f2d96..c68a32e 100644
--- a/src/jcl/jabber/command.py
+++ b/src/jcl/jabber/command.py
@@ -795,7 +795,7 @@ class JCLCommandManager(CommandManager):
def execute_get_user_lastlogin_3(self, info_query, session_context,
command_node, lang_class):
- self.__logger.debug("Executing command 'get-user-roster' step 2")
+ self.__logger.debug("Executing command 'get-user-roster' step 3")
result_form = Form(xmlnode_or_type="result")
result_form.add_field(field_type="hidden",
name="FORM_TYPE",
diff --git a/src/jcl/tests/__init__.py b/src/jcl/tests/__init__.py
index e1105f4..7f9cfe0 100644
--- a/src/jcl/tests/__init__.py
+++ b/src/jcl/tests/__init__.py
@@ -5,6 +5,8 @@ import unittest
import os
import tempfile
import sys
+import types
+import libxml2
from sqlobject.dbconnection import TheURIOpener
import jcl.model
@@ -14,6 +16,329 @@ if sys.platform == "win32":
else:
DB_DIR = "/tmp/"
+def is_xml_equal(xml_ref, xml_test, strict=False, test_sibling=True):
+ """
+ Test for xml structures equality.
+ By default (`strict`=False), it only test if `xml_ref` structure is included
+ in `xml_test` (ie. if all elements of `xml_ref` exists in `xml_test`).
+ if `strict`=True, it also checks if all elements of `xml_test` are in `xml_ref`.
+ siblings are tested only if `test_sibling` is True.
+ `xml_ref`.
+ `xml_ref`: xml node
+ `xml_test`: xml node
+ `strict`: boolean
+ `test_sibling`: boolean
+ """
+ if (xml_ref is None) ^ (xml_test is None):
+ if strict or xml_test is None:
+ return False
+ else:
+ return True
+ if (xml_ref is None) and (xml_test is None):
+ return True
+ if isinstance(xml_ref, types.StringType):
+ xml_ref = libxml2.parseDoc(xml_ref)
+ if isinstance(xml_test, types.StringType):
+ xml_test = libxml2.parseDoc(xml_test)
+
+ def check_equality(test_func, ref, test, strict):
+ """
+ Check equality with testing function `test_func`. If `strict` is
+ False, test xml node equality (without its siblings)
+ """
+ if not test_func(ref, test):
+ if strict:
+ return False
+ else:
+ if test.next is not None:
+ return is_xml_equal(ref, test.next, strict, False)
+ else:
+ return False
+ else:
+ return True
+
+ if not check_equality(lambda ref, test: ref.type == test.type,
+ xml_ref, xml_test, strict):
+ return False
+
+ if not check_equality(lambda ref, test: ref.name == test.name,
+ xml_ref, xml_test, strict):
+ return False
+
+ if not check_equality(lambda ref, test: ref.ns() == test.ns(),
+ xml_ref, xml_test, strict):
+ return False
+
+ def check_attribut_equality(ref, test):
+ """
+ Check if `ref` xml node attributs are in `test` xml node.
+ if `strict` is True, check if `test` attributs are in `ref` xml node.
+ """
+ if ref.properties is not None:
+ if test.properties is None:
+ return False
+ for attr in ref.properties:
+ if ref.prop(attr.name) != test.prop(attr.name):
+ return False
+ if strict:
+ for attr in test.properties:
+ if ref.prop(attr.name) != test.prop(attr.name):
+ return False
+ elif strict and test.properties is not None:
+ return False
+ return True
+
+ if not check_equality(check_attribut_equality,
+ xml_ref, xml_test, strict):
+ return False
+
+ if not check_equality(lambda ref, test: \
+ is_xml_equal(ref.children, test.children, strict),
+ xml_ref, xml_test, strict):
+ return False
+
+ if test_sibling:
+ if strict:
+ new_xml_test = xml_test.next
+ else:
+ new_xml_test = xml_test
+ if not check_equality(lambda ref, test: \
+ is_xml_equal(ref, test, strict),
+ xml_ref.next, new_xml_test, strict):
+ return False
+ return True
+
+class JCLTest_TestCase(unittest.TestCase):
+ ###########################################################################
+ ## Test weak equality
+ ###########################################################################
+ def test_is_xml_equal_simple_str_node_weak_equal(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2 equals
+ structures.
+ """
+ self.assertTrue(is_xml_equal("", ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents structures (attribut added).
+ """
+ self.assertTrue(is_xml_equal("", ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different_missing_attribut(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents structures (attribut missing).
+ """
+ self.assertFalse(is_xml_equal("", ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different_subnode(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents structures (subnode added).
+ """
+ self.assertTrue(is_xml_equal("", ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different_node(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents nodes.
+ """
+ self.assertFalse(is_xml_equal("", ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different_attribut(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents structures (different attributs).
+ """
+ self.assertFalse(is_xml_equal("",
+ ""))
+
+ def test_is_xml_equal_simple_str_node_weak_different_attribut_value(self):
+ """
+ Test with only one node (as string) weak equality (inclusion) 2
+ differents structures (different attributs values).
+ """
+ self.assertFalse(is_xml_equal("",
+ ""))
+
+ def test_is_xml_equal_complex_str_node_weak_equal(self):
+ """
+ Test 2 complex equal xml structures (weak equality).
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different_node_order(self):
+ """
+ Test 2 complex equal xml structures (weak equality) but with different
+ node order.
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different_attribut_order(self):
+ """
+ Test 2 complex equal xml structures (weak equality) but with different
+ attribut order.
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different(self):
+ """
+ Test 2 complex not strictly equal (attribut added) xml structures
+ (weak equality).
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different_missing_attribut(self):
+ """
+ Test 2 complex not strictly equal (missing attribut) xml structures
+ (weak equality).
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different_subnode(self):
+ """
+ Test 2 complex not strictly equal (subnode added) xml structures
+ (weak equality).
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ def test_is_xml_equal_complex_str_node_weak_different_siblingnode(self):
+ """
+ Test 2 complex not strictly equal (sibling node added) xml structures
+ (weak equality).
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """"""))
+
+ ###########################################################################
+ ## Test strict equality
+ ###########################################################################
+ def test_is_xml_equal_simple_str_node_strict_equal(self):
+ """
+ Test with only one node (as string) strict equality 2 equals
+ structures.
+ """
+ self.assertTrue(is_xml_equal("", "", True))
+
+ def test_is_xml_equal_simple_str_node_strict_different(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents structures (attribut added).
+ """
+ self.assertFalse(is_xml_equal("", "",
+ True))
+
+ def test_is_xml_equal_simple_str_node_strict_different(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents structures (attribut missing).
+ """
+ self.assertFalse(is_xml_equal("", "",
+ True))
+
+ def test_is_xml_equal_simple_str_node_strict_different_subnode(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents structures (subnode added).
+ """
+ self.assertFalse(is_xml_equal("", "",
+ True))
+
+ def test_is_xml_equal_simple_str_node_strict_different_node(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents nodes.
+ """
+ self.assertFalse(is_xml_equal("", "", True))
+
+ def test_is_xml_equal_simple_str_node_strict_different_attribut(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents structures (different attributs).
+ """
+ self.assertFalse(is_xml_equal("",
+ "",
+ True))
+
+ def test_is_xml_equal_simple_str_node_strict_different_attribut_value(self):
+ """
+ Test with only one node (as string) strict equality 2
+ differents structures (different attributs values).
+ """
+ self.assertFalse(is_xml_equal("",
+ "",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_equal(self):
+ """
+ Test 2 complex equal xml structures (strict equality).
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different_node_order(self):
+ """
+ Test 2 complex equal xml structures but with different
+ node order.
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different_attribut_order(self):
+ """
+ Test 2 complex equal xml structures but with different
+ attribut order.
+ """
+ self.assertTrue(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different(self):
+ """
+ Test 2 complex not strictly equal (attribut added) xml structures
+ (strict equality).
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different_missing_attribut(self):
+ """
+ Test 2 complex not strictly equal (missing attribut) xml structures
+ (strict equality).
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different_subnode(self):
+ """
+ Test 2 complex not strictly equal (subnode added) xml structures
+ (strict equality).
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """""",
+ True))
+
+ def test_is_xml_equal_complex_str_node_strict_different_siblingnode(self):
+ """
+ Test 2 complex not strictly equal (sibling node added) xml structures
+ (strict equality).
+ """
+ self.assertFalse(is_xml_equal("""""",
+ """""",
+ True))
+
class JCLTestCase(unittest.TestCase):
def __init__(self, methodName='runTest'):
unittest.TestCase.__init__(self, methodName)
@@ -50,6 +375,7 @@ def suite():
test_suite.addTest(runner.suite())
test_suite.addTest(jabber.suite())
test_suite.addTest(model.suite())
+ test_suite.addTest(unittest.makeSuite(JCLTest_TestCase, 'test'))
return test_suite
if __name__ == '__main__':