]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Improve parser readability + add unit tests
authorZane Bitter <zbitter@redhat.com>
Tue, 5 Jun 2012 13:02:45 +0000 (15:02 +0200)
committerZane Bitter <zbitter@redhat.com>
Tue, 5 Jun 2012 13:51:20 +0000 (15:51 +0200)
Change-Id: I7dd8c394e6543d1ee545648af32c9025c522b6e0
Signed-off-by: Zane Bitter <zbitter@redhat.com>
heat/engine/parser.py
heat/tests/test_parser.py [new file with mode: 0644]

index a31e7cffc04af2c5343ef6eedfa85c2d405ef029..b37a79ae9a0bd8e1e1327436efa9d8f01689652f 100644 (file)
@@ -426,19 +426,14 @@ def _resolve(match, handle, snippet):
 
     Returns a copy of the original snippet with the substitutions performed.
     '''
-    recurse = lambda k: _resolve(match, handle, snippet[k])
+    recurse = lambda s: _resolve(match, handle, s)
 
     if isinstance(snippet, dict):
-        should_handle = lambda k: match(k, snippet[k])
-        matches = itertools.imap(recurse,
-                                 itertools.ifilter(should_handle, snippet))
-        try:
-            args = next(matches)
-        except StopIteration:
-            # No matches
-            return dict((k, recurse(k)) for k in snippet)
-        else:
-            return handle(args)
+        if len(snippet) == 1:
+            k, v = snippet.items()[0]
+            if match(k, v):
+                return handle(recurse(v))
+        return dict((k, recurse(v)) for k, v in snippet.items())
     elif isinstance(snippet, list):
-        return [recurse(i) for i in range(len(snippet))]
+        return [recurse(v) for v in snippet]
     return snippet
diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py
new file mode 100644 (file)
index 0000000..449e8f4
--- /dev/null
@@ -0,0 +1,82 @@
+import nose
+import unittest
+from nose.plugins.attrib import attr
+
+from heat.engine.parser import _resolve as resolve
+
+
+def join(raw):
+    def handle_join(args):
+        delim, strs = args
+        return delim.join(strs)
+
+    return resolve(lambda k, v: k == 'Fn::Join', handle_join, raw)
+
+
+@attr(tag=['unit', 'parser'])
+@attr(speed='fast')
+class ParserTest(unittest.TestCase):
+
+    def test_list(self):
+        raw = ['foo', 'bar', 'baz']
+        parsed = join(raw)
+        for i in xrange(len(raw)):
+            self.assertEqual(parsed[i], raw[i])
+        self.assertTrue(parsed is not raw)
+
+    def test_dict(self):
+        raw = {'foo': 'bar', 'blarg': 'wibble'}
+        parsed = join(raw)
+        for k in raw:
+            self.assertEqual(parsed[k], raw[k])
+        self.assertTrue(parsed is not raw)
+
+    def test_dict_list(self):
+        raw = {'foo': ['bar', 'baz'], 'blarg': 'wibble'}
+        parsed = join(raw)
+        self.assertEqual(parsed['blarg'], raw['blarg'])
+        for i in xrange(len(raw['foo'])):
+            self.assertEqual(parsed['foo'][i], raw['foo'][i])
+        self.assertTrue(parsed is not raw)
+        self.assertTrue(parsed['foo'] is not raw['foo'])
+
+    def test_list_dict(self):
+        raw = [{'foo': 'bar', 'blarg': 'wibble'}, 'baz', 'quux']
+        parsed = join(raw)
+        for i in xrange(1, len(raw)):
+            self.assertEqual(parsed[i], raw[i])
+        for k in raw[0]:
+            self.assertEqual(parsed[0][k], raw[0][k])
+        self.assertTrue(parsed is not raw)
+        self.assertTrue(parsed[0] is not raw[0])
+
+    def test_join(self):
+        raw = {'Fn::Join': [' ', ['foo', 'bar', 'baz']]}
+        self.assertEqual(join(raw), 'foo bar baz')
+
+    def test_join_list(self):
+        raw = [{'Fn::Join': [' ', ['foo', 'bar', 'baz']]}, 'blarg', 'wibble']
+        parsed = join(raw)
+        self.assertEqual(parsed[0], 'foo bar baz')
+        for i in xrange(1, len(raw)):
+            self.assertEqual(parsed[i], raw[i])
+        self.assertTrue(parsed is not raw)
+
+    def test_join_dict_val(self):
+        raw = {'quux': {'Fn::Join': [' ', ['foo', 'bar', 'baz']]},
+               'blarg': 'wibble'}
+        parsed = join(raw)
+        self.assertEqual(parsed['quux'], 'foo bar baz')
+        self.assertEqual(parsed['blarg'], raw['blarg'])
+        self.assertTrue(parsed is not raw)
+
+    def test_join_recursive(self):
+        raw = {'Fn::Join': ['\n', [{'Fn::Join': [' ', ['foo', 'bar']]},
+                                  'baz']]}
+        self.assertEqual(join(raw), 'foo bar\nbaz')
+
+
+# allows testing of the test directly, shown below
+if __name__ == '__main__':
+    sys.argv.append(__file__)
+    nose.main()