From 6be4552dbf2159f589eb3f32742fee392e9d93c5 Mon Sep 17 00:00:00 2001
From: Nicolas Dumazet <nicolas.dumazet@nexedi.com>
Date: Tue, 5 Jan 2010 02:56:19 +0000
Subject: [PATCH] TestTradeModelLine: check all possible orders for
 contribution/application list

This was responsible for the recent failure of the test.
Remove the two XXX and use instead a assertMatchesPossibleSortList to match all
possible combinations


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@31564 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/tests/testTradeModelLine.py | 66 +++++++++++++++++++++---
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/product/ERP5/tests/testTradeModelLine.py b/product/ERP5/tests/testTradeModelLine.py
index 24e25db0ce..253080a991 100644
--- a/product/ERP5/tests/testTradeModelLine.py
+++ b/product/ERP5/tests/testTradeModelLine.py
@@ -1570,6 +1570,46 @@ class TestTradeModelLine(TestTradeModelLineMixin):
     self.assertEquals([q.getReference() for q in trade_model_line_list],
         [q.getReference() for q in [A, C, B,]])
 
+  def assertMatchesPossibleSortList(self, candidate, expected_sort_list):
+    """
+    expected_sort_list is a list of possible sort. Example of a sort:
+      (DEFG) (BC) A
+      where everything in parenthesis can be not sorted
+    Each possible sort is represented as a list of list
+    For example, the possible sort (FG) C (DE) B A is represented as
+    [ [F, G], [C], [D, E], [B], [A] ]
+
+    candidate, in the other hand, is a simple list, for example
+      [F, G, C, D, E, B, A]
+
+    This function raises AssertionError if candidate does not match
+    one of the possible sorts
+    """
+    candidate_length = len(candidate)
+
+    for expected_sort in expected_sort_list:
+      i = 0
+      matching = True
+      while expected_sort and i < candidate_length:
+        current_head = expected_sort[0]
+        if candidate[i] in current_head:
+          current_head.remove(candidate[i])
+          if len(current_head) == 0:
+            expected_sort.pop(0)
+          i += 1
+        else:
+          matching = False
+          break
+
+      if matching and len(expected_sort) == 0 and i == candidate_length:
+        # we found a matching sort
+        return
+
+    # None of the possibilities matched, raise an error:
+    sort_list_representation = "\n".join(map(repr, expected_sort_list))
+    raise AssertionError("%s does not match one of the possible sorts:\n%s"
+        % (candidate, sort_list_representation))
+
 
   def test_getTradeModelLineComposedList(self):
     """Test that list of contribution/application relations is sorted to do easy traversal
@@ -1623,9 +1663,17 @@ class TestTradeModelLine(TestTradeModelLineMixin):
 
     trade_model_line_list = trade_condition.getTradeModelLineComposedList()
 
-    # XXX: This is only one good possible sorting
-    self.assertEquals([q.getReference() for q in trade_model_line_list],
-        [q.getReference() for q in [G, F, E, D, C, B, A]])
+    possible_sort_list = [
+                          [[D,E], [B], [F, G], [C], [A]],
+                          [[F,G], [C], [D, E], [B], [A]],
+                          [[D,E,F,G], [B,C], [A]],
+                         ]
+    def get_ref(l):
+      return map(lambda x:x.getReference(), l)
+
+    possible_sort_ref_list = [map(get_ref, sort) for sort in possible_sort_list]
+    self.assertMatchesPossibleSortList(get_ref(trade_model_line_list),
+                                        possible_sort_ref_list)
 
   def test_getComplexTradeModelLineComposedList(self):
     """Test that list of contribution/application relations is sorted to do easy traversal
@@ -1662,9 +1710,15 @@ class TestTradeModelLine(TestTradeModelLineMixin):
 
     trade_model_line_list = trade_condition.getTradeModelLineComposedList()
 
-    # XXX: This is only one good possible sorting
-    self.assertEquals([q.getReference() for q in trade_model_line_list],
-        [q.getReference() for q in [A, B, C, D]])
+    possible_sort_list = [
+                          [[A], [B,C], [D]]
+                         ]
+    def get_ref(l):
+      return map(lambda x:x.getReference(), l)
+
+    possible_sort_ref_list = [map(get_ref, sort) for sort in possible_sort_list]
+    self.assertMatchesPossibleSortList(get_ref(trade_model_line_list),
+                                        possible_sort_ref_list)
 
   def test_tradeModelLineWithFixedPrice(self):
     """
-- 
2.30.9