[PATCH 3/4] Fix tests

Richard Maw richard.maw at codethink.co.uk
Mon Jan 21 18:15:59 GMT 2013


Invalid text changed to be something that doesn't parse as YAML
either, and catch convert the YAMLError to the expected exception.

Ideally there wouldn't be any `#pragma: no cover`s, but I could not
trigger these code paths.
---
 morphlib/__init__.py                |    2 +-
 morphlib/morph2_tests.py            |   19 +++++++++-
 morphlib/morphologyfactory.py       |    6 ++-
 morphlib/morphologyfactory_tests.py |    6 +--
 morphlib/yamlparse.py               |   33 +++++++++++------
 morphlib/yamlparse_tests.py         |   69 +++++++++++++++++++++++++++++++++++
 tests.as-root/lib                   |    2 +-
 7 files changed, 116 insertions(+), 21 deletions(-)
 create mode 100644 morphlib/yamlparse_tests.py

diff --git a/morphlib/__init__.py b/morphlib/__init__.py
index ad2e76d..5730d41 100644
--- a/morphlib/__init__.py
+++ b/morphlib/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2012  Codethink Limited
+# Copyright (C) 2011-2013  Codethink Limited
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/morphlib/morph2_tests.py b/morphlib/morph2_tests.py
index 756873a..34df465 100644
--- a/morphlib/morph2_tests.py
+++ b/morphlib/morph2_tests.py
@@ -22,7 +22,7 @@ from morphlib.morph2 import Morphology
 
 class MorphologyTests(unittest.TestCase):
 
-    def test_parses_simple_chunk(self):
+    def test_parses_simple_json_chunk(self):
         m = Morphology('''
             {
                 "name": "foo",
@@ -41,6 +41,23 @@ class MorphologyTests(unittest.TestCase):
         self.assertEqual(m['max-jobs'], None)
         self.assertEqual(m['chunks'], [])
 
+    def test_parses_simple_yaml_chunk(self):
+        m = Morphology('''
+            name: foo
+            kind: chunk
+            build-system: manual
+        ''')
+
+        self.assertEqual(m['name'], 'foo')
+        self.assertEqual(m['kind'], 'chunk')
+        self.assertEqual(m['build-system'], 'manual')
+        self.assertEqual(m['configure-commands'], None)
+        self.assertEqual(m['build-commands'], None)
+        self.assertEqual(m['test-commands'], None)
+        self.assertEqual(m['install-commands'], None)
+        self.assertEqual(m['max-jobs'], None)
+        self.assertEqual(m['chunks'], [])
+
     def test_sets_stratum_chunks_repo_and_morph_from_name(self):
         m = Morphology('''
             {
diff --git a/morphlib/morphologyfactory.py b/morphlib/morphologyfactory.py
index a219ed9..261dc90 100644
--- a/morphlib/morphologyfactory.py
+++ b/morphlib/morphologyfactory.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Codethink Limited
+# Copyright (C) 2012-2013  Codethink Limited
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -13,6 +13,8 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
+import yaml
+
 import morphlib
 import cliapp
 
@@ -81,7 +83,7 @@ class MorphologyFactory(object):
 
         try:
             morphology = morphlib.morph2.Morphology(text)
-        except ValueError as e:
+        except yaml.YAMLError as e:
             raise morphlib.Error("Error parsing %s: %s" %
                                  (filename, str(e)))
 
diff --git a/morphlib/morphologyfactory_tests.py b/morphlib/morphologyfactory_tests.py
index b8c89d2..56c6fc5 100644
--- a/morphlib/morphologyfactory_tests.py
+++ b/morphlib/morphologyfactory_tests.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Codethink Limited
+# Copyright (C) 2012-2013  Codethink Limited
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -65,9 +65,7 @@ class FakeLocalRepo(object):
                 "system-kind": "%(system_kind)s",
                 "arch": "%(arch)s"
             }''',
-        'parse-error.morph': '''{
-                "name"
-            }''',
+        'parse-error.morph': '''{ "name"''',
     }
 
     def __init__(self):
diff --git a/morphlib/yamlparse.py b/morphlib/yamlparse.py
index 1567a3c..275a24f 100644
--- a/morphlib/yamlparse.py
+++ b/morphlib/yamlparse.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Codethink Limited
+# Copyright (C) 2013  Codethink Limited
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -26,7 +26,8 @@ class OrderedDictYAMLLoader(yaml.Loader):
     def __init__(self, *args, **kwargs):
         yaml.Loader.__init__(self, *args, **kwargs)
 
-        self.add_constructor(u'tag:yaml.org,2002:map', type(self).construct_yaml_map)
+        self.add_constructor(u'tag:yaml.org,2002:map',
+                             type(self).construct_yaml_map)
 
     def construct_yaml_map(self, node):
         data = OrderedDict()
@@ -38,8 +39,10 @@ class OrderedDictYAMLLoader(yaml.Loader):
         if isinstance(node, yaml.MappingNode):
             self.flatten_mapping(node)
         else:
-            raise yaml.constructor.ConstructorError(None, None,
-                'expected a mapping node, but found %s' % node.id, node.start_mark)
+            raise yaml.constructor.ConstructorError(
+                None, None,
+                'expected a mapping node, but found %s' % node.id,
+                node.start_mark)
 
         mapping = OrderedDict()
         for key_node, value_node in node.value:
@@ -47,8 +50,10 @@ class OrderedDictYAMLLoader(yaml.Loader):
             try:
                 hash(key)
             except TypeError, exc:
-                raise yaml.constructor.ConstructorError('while constructing a mapping',
-                    node.start_mark, 'found unacceptable key (%s)' % exc, key_node.start_mark)
+                raise yaml.constructor.ConstructorError(
+                    'while constructing a mapping',
+                    node.start_mark, 'found unacceptable key (%s)' % exc,
+                    key_node.start_mark)
             value = self.construct_object(value_node, deep=deep)
             mapping[key] = value
         return mapping
@@ -73,19 +78,23 @@ class OrderedDictYAMLDumper(yaml.Dumper):
         for item_key, item_value in omap.iteritems():
             node_key = self.represent_data(item_key)
             node_value = self.represent_data(item_value)
-            if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
-                best_style = False
-            if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style):
-                best_style = False
+            if not (isinstance(node_key, yaml.ScalarNode) and
+                    not node_key.style):
+                best_style = False # pragma: no cover
+            if not (isinstance(node_value, yaml.ScalarNode) and
+                    not node_value.style):
+                best_style = False # pragma: no cover
             value.append((node_key, node_value))
         if self.default_flow_style is not None:
             node.flow_style = self.default_flow_style
         else:
-            node.flow_style = best_style
+            node.flow_style = best_style # pragma: no cover
         return node
 
 def load(*args, **kwargs):
     return yaml.load(Loader=OrderedDictYAMLLoader, *args, **kwargs)
 
 def dump(*args, **kwargs):
-    return yaml.dump(Dumper=OrderedDictYAMLDumper, default_flow_style=False, *args, **kwargs)
+    if 'default_flow_style' not in kwargs:
+        kwargs['default_flow_style'] = False
+    return yaml.dump(Dumper=OrderedDictYAMLDumper, *args, **kwargs)
diff --git a/morphlib/yamlparse_tests.py b/morphlib/yamlparse_tests.py
new file mode 100644
index 0000000..cb658e1
--- /dev/null
+++ b/morphlib/yamlparse_tests.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2013  Codethink Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import unittest
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict
+import yaml
+
+import morphlib.yamlparse as yamlparse
+
+
+class YAMLParseTests(unittest.TestCase):
+
+    example_text = '''\
+name: foo
+kind: chunk
+build-system: manual
+'''
+
+    example_dict = OrderedDict([
+        ('name', 'foo'),
+        ('kind', 'chunk'),
+        ('build-system', 'manual'),
+    ])
+
+    def test_loads_as_ordered_dict(self):
+        m = yamlparse.load(self.example_text)
+        self.assertEqual(type(m), OrderedDict)
+
+    def test_dumps_ordered_dicts(self):
+        self.assertEqual(self.example_text,
+                         yamlparse.dump(self.example_dict))
+
+    def test_non_map_raises(self):
+        incorrect_type = '''\
+!!map
+- foo
+- bar
+'''
+        self.assertRaises(yaml.YAMLError, yamlparse.load, incorrect_type)
+
+    def test_complex_key_fails_KNOWNFAILURE(self):
+        complex_key = '? { foo: bar, baz: qux }: True'
+        self.assertRaises(yaml.YAMLError, yamlparse.load, complex_key)
+
+    def test_represents_non_scalar_nodes(self):
+        self.assertTrue(
+            yamlparse.dump(
+                {
+                    ('a', 'b'): {
+                        "foo": 1,
+                        "bar": 2,
+                    }
+                }, default_flow_style=None))
diff --git a/tests.as-root/lib b/tests.as-root/lib
index d17d8e3..cdeb1ce 100644
--- a/tests.as-root/lib
+++ b/tests.as-root/lib
@@ -22,7 +22,7 @@ loopback_rootfs() {
     # Find offset partition offset in a rootfs and mount it
     ROOTFS="$1"
 
-    PYTHONPATH="$SRCDIR" "$SRCDIR/scripts/sparse-gunzip" \
+    PYTHONPATH="$PYTHONPATH:$SRCDIR" "$SRCDIR/scripts/sparse-gunzip" \
                          <"$ROOTFS" >"$ROOTFS-unzipped"
 
     OFFSET=$(sfdisk -d "$ROOTFS-unzipped" | \
-- 
1.7.5.4





More information about the baserock-dev mailing list