Revision: 88581e2baa60
Branch:   default
Author:   Pekka Klärck
Date:     Fri Jan 24 00:22:03 2014 UTC
Log:      Tag patterns: Support for OR in Python side.

Update issue 1558
Status: Started
Owner: pekka.klarck
Implemented the support on Python side with help of unit tests. This seems to work already e.g. with --include, but that needs to be separately tested on higher level. Other tasks include implementing this also on JavaScript and documentation in UG and possibly also in --help.
http://code.google.com/p/robotframework/source/detail?r=88581e2baa60

Modified:
 /src/robot/model/tags.py
 /utest/model/test_tags.py

=======================================
--- /src/robot/model/tags.py    Thu Jan 23 14:00:53 2014 UTC
+++ /src/robot/model/tags.py    Fri Jan 24 00:22:03 2014 UTC
@@ -97,6 +97,8 @@
     pattern = pattern.replace('&', 'AND')
     if 'NOT' in pattern:
         return _NotTagPattern(*pattern.split('NOT'))
+    if 'OR' in pattern:
+        return _OrTagPattern(pattern.split('OR'))
     if 'AND' in pattern:
         return _AndTagPattern(pattern.split('AND'))
     return _SingleTagPattern(pattern)
@@ -123,12 +125,20 @@
         return all(p.match(tags) for p in self._patterns)


+class _OrTagPattern(object):
+
+    def __init__(self, patterns):
+        self._patterns = tuple(TagPattern(p) for p in patterns)
+
+    def match(self, tags):
+        return any(p.match(tags) for p in self._patterns)
+
+
 class _NotTagPattern(object):

     def __init__(self, must_match, *must_not_match):
-        self._must = TagPattern(must_match)
-        self._must_not = tuple(TagPattern(m) for m in must_not_match)
+        self._first = TagPattern(must_match)
+        self._rest = _OrTagPattern(must_not_match)

     def match(self, tags):
-        return self._must.match(tags) \
-            and not any(p.match(tags) for p in self._must_not)
+        return self._first.match(tags) and not self._rest.match(tags)
=======================================
--- /utest/model/test_tags.py   Tue Jun  4 08:47:43 2013 UTC
+++ /utest/model/test_tags.py   Fri Jan 24 00:22:03 2014 UTC
@@ -174,21 +174,54 @@

 class TestTagPatterns(unittest.TestCase):

-    def test_match(self):
+    def test_single_pattern(self):
         patterns = TagPatterns(['x', 'y', 'z*'])
         assert_false(patterns.match([]))
         assert_false(patterns.match(['no', 'match']))
         assert_true(patterns.match(['x']))
         assert_true(patterns.match(['xxx', 'zzz']))

-    def test_match_with_and(self):
+    def test_and(self):
         patterns = TagPatterns(['xANDy', '???ANDz'])
         assert_false(patterns.match([]))
         assert_false(patterns.match(['x']))
         assert_true(patterns.match(['x', 'y', 'z']))
         assert_true(patterns.match(['123', 'y', 'z']))

-    def test_match_with_not(self):
+    def test_multiple_ands(self):
+        patterns = TagPatterns(['xANDyANDz'])
+        assert_false(patterns.match([]))
+        assert_false(patterns.match(['x']))
+        assert_false(patterns.match(['x', 'y']))
+        assert_true(patterns.match(['x', 'Y', 'z']))
+        assert_true(patterns.match(['a', 'y', 'z', 'b', 'X']))
+
+    def test_or(self):
+        patterns = TagPatterns(['xORy', '???ORz'])
+        assert_false(patterns.match([]))
+        assert_false(patterns.match(['a', 'b', '12', '1234']))
+        assert_true(patterns.match(['x']))
+        assert_true(patterns.match(['Y']))
+        assert_true(patterns.match(['123']))
+        assert_true(patterns.match(['Z']))
+        assert_true(patterns.match(['x', 'y', 'z']))
+        assert_true(patterns.match(['123', 'a', 'b', 'c', 'd']))
+        assert_true(patterns.match(['a', 'b', 'c', 'd', 'Z']))
+
+    def test_multiple_ors(self):
+        patterns = TagPatterns(['xORyORz'])
+        assert_false(patterns.match([]))
+        assert_false(patterns.match(['xxx']))
+        assert_true(all(patterns.match([c]) for c in 'XYZ'))
+        assert_true(all(patterns.match(['a', 'b', c, 'd']) for c in 'xyz'))
+        assert_true(patterns.match(['x', 'y']))
+        assert_true(patterns.match(['x', 'Y', 'z']))
+
+    def test_ands_and_ors(self):
+        for pattern in AndOrPatternGenerator(max_length=5):
+ assert_equal(TagPattern(pattern).match('1'), eval(pattern.lower()))
+
+    def test_not(self):
         patterns = TagPatterns(['xNOTy', '???NOT?'])
         assert_false(patterns.match([]))
         assert_false(patterns.match(['x', 'y']))
@@ -196,7 +229,7 @@
         assert_true(patterns.match(['x']))
         assert_true(patterns.match(['123', 'xx']))

-    def test_match_with_not_and_and(self):
+    def test_not_and_and(self):
         patterns = TagPatterns(['xNOTyANDz', 'aANDbNOTc',
                                 '1 AND 2? AND 3?? NOT 4* AND 5* AND 6*'])
         assert_false(patterns.match([]))
@@ -213,7 +246,27 @@
         assert_true(patterns.match(['1', '22', '333']))
         assert_true(patterns.match(['1', '22', '333', '4', '5', '7']))

-    def test_match_with_multiple_nots(self):
+    def test_not_and_or(self):
+        patterns = TagPatterns(['xNOTyORz', 'aORbNOTc',
+                                '1 OR 2? OR 3?? NOT 4* OR 5* OR 6*'])
+        assert_false(patterns.match([]))
+        assert_false(patterns.match(['x', 'y', 'z']))
+        assert_false(patterns.match(['x', 'y']))
+        assert_false(patterns.match(['Z', 'x']))
+        assert_true(patterns.match(['x']))
+        assert_true(patterns.match(['xxx', 'X']))
+        assert_true(patterns.match(['a', 'b']))
+        assert_false(patterns.match(['a', 'b', 'c']))
+        assert_true(patterns.match(['a']))
+        assert_true(patterns.match(['B', 'XXX']))
+        assert_false(patterns.match(['b', 'c']))
+        assert_false(patterns.match(['c']))
+        assert_true(patterns.match(['x', 'y', '321']))
+        assert_false(patterns.match(['x', 'y', '32']))
+        assert_false(patterns.match(['1', '2', '3', '4']))
+        assert_true(patterns.match(['1', '22', '333']))
+
+    def test_multiple_nots(self):
         patterns = TagPatterns(['xNOTyNOTz', '1 NOT 2 NOT 3 NOT 4'])
         assert_true(patterns.match(['x']))
         assert_false(patterns.match(['x', 'y']))
@@ -225,7 +278,7 @@
         assert_false(patterns.match(['1', '2', '3']))
         assert_false(patterns.match(['1', '2', '3', '4']))

-    def test_match_with_multiple_nots_with_ands(self):
+    def test_multiple_nots_with_ands(self):
         patterns = TagPatterns('a AND b NOT c AND d NOT e AND f')
         assert_true(patterns.match(['a', 'b']))
         assert_true(patterns.match(['a', 'b', 'c']))
@@ -235,10 +288,40 @@
         assert_false(patterns.match(['a', 'b', 'c', 'd', 'e', 'f']))
         assert_false(patterns.match(['a', 'b', 'c', 'd', 'e']))

+    def test_multiple_nots_with_ors(self):
+        patterns = TagPatterns('a OR b NOT c OR d NOT e OR f')
+        assert_true(patterns.match(['a']))
+        assert_true(patterns.match(['B']))
+        assert_false(patterns.match(['c']))
+        assert_true(all(not patterns.match(['a', 'b', c]) for c in 'cdef'))
+        assert_true(patterns.match(['a', 'x']))
+
     def test_seq2str(self):
         patterns = TagPatterns([u'is\xe4', u'\xe4iti'])
         assert_equal(utils.seq2str(patterns), u"'is\xe4' and '\xe4iti'")


+class AndOrPatternGenerator(object):
+    tags = ['0', '1']
+    operators = ['OR', 'AND']
+
+    def __init__(self, max_length):
+        self.max_length = max_length
+
+    def __iter__(self):
+        for tag in self.tags:
+            for pattern in self._generate([tag], self.max_length-1):
+                yield pattern
+
+    def _generate(self, tokens, length):
+        yield ' '.join(tokens)
+        if length:
+            for operator in self.operators:
+                for tag in self.tags:
+                    for pattern in self._generate(tokens + [operator, tag],
+                                                  length-1):
+                        yield pattern
+
+
 if __name__ == '__main__':
     unittest.main()

--

--- You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to