--- a/test/unittest_editextensions.py Thu May 19 09:58:09 2011 +0200
+++ b/test/unittest_editextensions.py Wed May 25 15:39:36 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2004-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of rql.
@@ -19,10 +19,11 @@
from logilab.common.testlib import TestCase, unittest_main
from rql import parse
+from rql.nodes import Exists
from rql.editextensions import *
class RQLUndoTestCase(TestCase):
-
+
def test_selected(self):
rqlst = parse('Person X')
orig = rqlst.as_string()
@@ -40,7 +41,7 @@
self.assertEqual(rqlst.as_string(), orig)
# check references after recovering
rqlst.check_references()
-
+
def test_selected3(self):
rqlst = parse('Any lower(N) WHERE X is Person, X name N')
orig = rqlst.as_string()
@@ -58,7 +59,7 @@
self.assertEqual(rqlst.as_string(), orig)
# check references after recovering
rqlst.check_references()
-
+
def test_undefine_1(self):
rqlst = parse('Person X, Y WHERE X travaille_pour Y')
orig = rqlst.as_string()
@@ -73,7 +74,7 @@
self.assertEqual(rqlst.as_string(), orig)
# check references after recovering
rqlst.check_references()
-
+
def test_undefine_2(self):
rqlst = parse('Person X')
orig = rqlst.as_string()
@@ -90,7 +91,24 @@
self.assertEqual(rqlst.as_string(), orig)
# check references after recovering
rqlst.check_references()
-
-
+
+
+ def test_remove_exists(self):
+ rqlst = parse('Any U,COUNT(P) GROUPBY U WHERE U is CWUser, P? patch_reviewer U, EXISTS(P in_state S AND S name "pouet")').children[0]
+ orig = rqlst.as_string()
+ rqlst.save_state()
+ n = [r for r in rqlst.get_nodes(Exists)][0].query
+ rqlst.remove_node(n)
+ # check operations
+ self.assertEqual(rqlst.as_string(), 'Any U,COUNT(P) GROUPBY U WHERE U is CWUser, P? patch_reviewer U')
+ # check references before recovering
+ rqlst.check_references()
+ rqlst.recover()
+ # check equivalence
+ self.assertEqual(rqlst.as_string(), orig)
+ # check references after recovering
+ rqlst.check_references()
+
+
if __name__ == '__main__':
unittest_main()
--- a/undo.py Thu May 19 09:58:09 2011 +0200
+++ b/undo.py Wed May 25 15:39:36 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2004-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of rql.
@@ -19,7 +19,7 @@
__docformat__ = "restructuredtext en"
-from rql.nodes import VariableRef, Variable, BinaryNode
+from rql.nodes import Exists, VariableRef, Variable, BinaryNode
from rql.stmts import Select
class SelectionManager(object):
@@ -142,8 +142,8 @@
def __init__(self, node, parent, stmt, index):
NodeOperation.__init__(self, node, stmt)
self.node_parent = parent
- #if isinstance(parent, Select):
- # assert self.node is parent.where
+ if index is None:
+ assert isinstance(parent, (Exists, Select)), (node, parent)
self.index = index
# XXX FIXME : find a better way to do that
self.binary_remove = isinstance(node, BinaryNode)
@@ -152,9 +152,11 @@
"""undo the operation on the selection"""
parent = self.node_parent
if self.index is None:
- assert isinstance(parent, Select)
- sibling = parent.where = self.node
- parent.where = self.node
+ if isinstance(parent, Select):
+ parent.where = self.node
+ else: # Exists
+ parent.query = self.node
+ sibling = self.node
if self.binary_remove:
# if 'parent' was a BinaryNode, then first reinsert the removed node
# at the same pos in the original 'parent' Binary Node, and then