From d950213c90288ea1e636f2fdaa3da4ee2aec4d1a Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <vincent@nexedi.com>
Date: Wed, 20 May 2009 08:59:04 +0000
Subject: [PATCH] Improve usability of SimpleQuery when directly instanciated:
 automaticaly convert an "=" comparison operator on a None value into an "is"
 comparison operator. Update code comment, as it is not about backward
 compatibility but about usability. Add a test.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@27070 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ZSQLCatalog/Query/SimpleQuery.py    |  9 ++++++++-
 product/ZSQLCatalog/tests/testSQLCatalog.py | 16 ++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/product/ZSQLCatalog/Query/SimpleQuery.py b/product/ZSQLCatalog/Query/SimpleQuery.py
index 846ce96f05..ff33b8f1f5 100644
--- a/product/ZSQLCatalog/Query/SimpleQuery.py
+++ b/product/ZSQLCatalog/Query/SimpleQuery.py
@@ -62,7 +62,7 @@ class SimpleQuery(Query):
     if len(kw) != 1:
       raise ValueError, 'SimpleQuery can support one and one only column. Got %r.' % (kw, )
     self.column, value = kw.popitem()
-    # Backward compatibility code (those changes should not be needed when
+    # Usability improvement code (those changes should not be needed when
     # this Query is instanciated by a SearchKey, as operator should be correct
     # already).
     comparison_operator = comparison_operator.lower()
@@ -83,6 +83,13 @@ class SimpleQuery(Query):
           value = value[0]
         else:
           comparison_operator = 'in'
+    if value is None:
+      if comparison_operator == '=':
+        comparison_operator = 'is'
+      elif comparison_operator != 'is':
+        raise ValueError, 'None value with a non-"=" comparison_operator (%r). Not sure what to do.' % (comparison_operator, )
+    elif comparison_operator == 'is':
+      raise ValueError, 'Non-None value (%r) with "is" comparison_operator. Not sure what to do.' % (value, )
     self.value = value
     self.comparison_operator = comparison_operator
     self.group = group
diff --git a/product/ZSQLCatalog/tests/testSQLCatalog.py b/product/ZSQLCatalog/tests/testSQLCatalog.py
index aac426c31b..b133afeeb8 100644
--- a/product/ZSQLCatalog/tests/testSQLCatalog.py
+++ b/product/ZSQLCatalog/tests/testSQLCatalog.py
@@ -406,6 +406,22 @@ class TestSQLCatalog(unittest.TestCase):
     self.catalog(ReferenceQuery(ReferenceQuery(ReferenceQuery(operator='match', fulltext='a b'), operator='not'), operator='and'),
                  {'fulltext': 'NOT (a b)'})
 
+  def test_NoneValueToSimpleQuery(self):
+    """
+      When a SimpleQuery receives a python None value and an "=" comparison
+      operator (be it the default or explictely provided), it must change that
+      operator into an "is" operator.
+      If "is" compariton operator is explicitely provided with a non-None
+      value, raise.
+      If non-"=" compariton operator is provided with a None value, raise.
+    """
+    self.assertEqual(ReferenceQuery(operator='is', default=None),
+                     SimpleQuery(default=None))
+    self.assertEqual(ReferenceQuery(operator='is', default=None),
+                     SimpleQuery(default=None, comparison_operator='='))
+    self.assertRaises(ValueError, SimpleQuery, default=None, comparison_operator='>=')
+    self.assertRaises(ValueError, SimpleQuery, default=1, comparison_operator='is')
+
 ##return catalog(title=Query(title='a', operator='not'))
 #return catalog(title={'query': 'a', 'operator': 'not'})
 #return catalog(title={'query': ['a', 'b'], 'operator': 'not'})
-- 
2.30.9