changeset 164:06c681ff53aa

Round-tripping through load/save shouldn't discard objects
author Neil Muller <drnlmuller@gmail.com>
date Tue, 03 Sep 2013 10:47:27 +0200
parents 5d00ee725617
children dba8bc454a43
files nagslang/level.py nagslang/tests/test_level.py
diffstat 2 files changed, 65 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/level.py	Tue Sep 03 01:21:24 2013 +0200
+++ b/nagslang/level.py	Tue Sep 03 10:47:27 2013 +0200
@@ -29,12 +29,22 @@
         self._exterior = False
         self._glue = go.PuzzleGlue()
         self._drawables = []
+        self._game_objects = []
 
     def _get_data(self):
         # For overriding in tests.
         with resources.get_file('levels', self.name) as f:
             return load(f)
 
+    def _dump_data(self, f):
+        # For manipulation in tests.
+        dump({
+            'size': [self.x, self.y],
+            'base_tile': self.basetile,
+            'polygons': self.polygons,
+            'game_objects': self._game_objects,
+        }, f)
+
     def load(self, space):
         data = self._get_data()
         self.x, self.y = data['size']
@@ -43,7 +53,8 @@
             self.polygons[i] = []
             for point in points:
                 self.polygons[i].append(tuple(point))
-        for game_object_dict in data.get('game_objects', []):
+        self._game_objects = data.get('game_objects', [])
+        for game_object_dict in self._game_objects:
             self._create_game_object(space, **game_object_dict)
 
     def _create_game_object(self, space, classname, args, name=None):
@@ -83,11 +94,7 @@
         if not closed:
             return False
         with resources.get_file('levels', self.name, mode='w') as f:
-            dump({
-                'size': [self.x, self.y],
-                'base_tile': self.basetile,
-                'polygons': self.polygons,
-            }, f)
+            self._dump_data(f)
         return True
 
     def get_size(self):
--- a/nagslang/tests/test_level.py	Tue Sep 03 01:21:24 2013 +0200
+++ b/nagslang/tests/test_level.py	Tue Sep 03 10:47:27 2013 +0200
@@ -1,7 +1,10 @@
 from unittest import TestCase
 
+from StringIO import StringIO
+
 from nagslang import game_object as go
 from nagslang.level import Level
+from nagslang.yamlish import load
 
 
 class FakeSpace(object):
@@ -15,18 +18,38 @@
         level._get_data = lambda: data
         return level
 
+    def roundtrip_level(self, level):
+        newlevel = Level(level.name)
+        f = StringIO()
+        level._dump_data(f)
+        f.seek(0)
+        newlevel._get_data = lambda: load(f)
+        return newlevel
+
     def test_empty_level(self):
+        def do_test(level):
+            level.load(FakeSpace())
+            self.assertEqual((5, 10), level.get_size())
+            self.assertEqual([], level.get_walls())
+            self.assertEqual([], level.get_drawables())
+
         level = self.make_level('foo', {
             'size': [5, 10],
             'base_tile': 'tiles/floor.png',
             'polygons': {},
         })
-        level.load(FakeSpace())
-        self.assertEqual((5, 10), level.get_size())
-        self.assertEqual([], level.get_walls())
-        self.assertEqual([], level.get_drawables())
+
+        do_test(level)
+        level2 = self.roundtrip_level(level)
+        do_test(level2)
 
     def test_level_walls(self):
+        def do_test(level):
+            level.load(FakeSpace())
+            self.assertEqual((5, 10), level.get_size())
+            self.assertEqual([[(1, 1), (2, 1), (1, 2)]], level.get_walls())
+            self.assertEqual([], level.get_drawables())
+
         level = self.make_level('foo', {
             'size': [5, 10],
             'base_tile': 'tiles/floor.png',
@@ -34,12 +57,30 @@
                 1: [[1, 1], [2, 1], [1, 2]],
             },
         })
-        level.load(FakeSpace())
-        self.assertEqual((5, 10), level.get_size())
-        self.assertEqual([[(1, 1), (2, 1), (1, 2)]], level.get_walls())
-        self.assertEqual([], level.get_drawables())
+        do_test(level)
+        level2 = self.roundtrip_level(level)
+        do_test(level2)
 
     def test_level_game_objects(self):
+        def do_test(level):
+            level.load(FakeSpace())
+            self.assertEqual((5, 10), level.get_size())
+            self.assertEqual([], level.get_walls())
+            [box, switch] = level.get_drawables()
+            self.assertTrue(isinstance(box, go.Box))
+            self.assertEqual(box.shape.body.position, (3, 3))
+            self.assertTrue(isinstance(switch, go.FloorSwitch))
+            self.assertEqual(switch.shape.body.position, (4, 4))
+
+            puzzle_bits = level._glue._components
+            self.assertEqual(['foo', 'foo_proxy'],
+                             sorted(puzzle_bits.keys()))
+            self.assertTrue(
+                isinstance(puzzle_bits['foo_proxy'], go.StateProxyPuzzler))
+            self.assertEqual('foo', puzzle_bits['foo_proxy']._state_source)
+            self.assertTrue(isinstance(puzzle_bits['foo'],
+                            go.FloorSwitchPuzzler))
+
         level = self.make_level('foo', {
             'size': [5, 10],
             'base_tile': 'tiles/floor.png',
@@ -61,18 +102,7 @@
                 },
             ],
         })
-        level.load(FakeSpace())
-        self.assertEqual((5, 10), level.get_size())
-        self.assertEqual([], level.get_walls())
-        [box, switch] = level.get_drawables()
-        self.assertTrue(isinstance(box, go.Box))
-        self.assertEqual(box.shape.body.position, (3, 3))
-        self.assertTrue(isinstance(switch, go.FloorSwitch))
-        self.assertEqual(switch.shape.body.position, (4, 4))
 
-        puzzle_bits = level._glue._components
-        self.assertEqual(['foo', 'foo_proxy'], sorted(puzzle_bits.keys()))
-        self.assertTrue(
-            isinstance(puzzle_bits['foo_proxy'], go.StateProxyPuzzler))
-        self.assertEqual('foo', puzzle_bits['foo_proxy']._state_source)
-        self.assertTrue(isinstance(puzzle_bits['foo'], go.FloorSwitchPuzzler))
+        do_test(level)
+        level2 = self.roundtrip_level(level)
+        do_test(level2)