Added test case for mutables to libbe/settings_object.
authorW. Trevor King <wking@drexel.edu>
Tue, 23 Jun 2009 23:52:20 +0000 (19:52 -0400)
committerW. Trevor King <wking@drexel.edu>
Tue, 23 Jun 2009 23:52:20 +0000 (19:52 -0400)
This continues the line of changes started in libbe/properties with
the last two commits.  Also straightened up stranch double-default in
libbe.settings_object.versioned_property and moved the fn_checked
before checked, which shouldn't matter because I never use both at
once, and can't think of a case where you'd want to.

I've also added some docstrings to the settings_object unit tests,
since apparently docstrings get printed during the test if they exist,
and they look nicer than the name of the unittest itself.  More like
./configure output ;).

libbe/settings_object.py

index 3cbfdda02ebe6a4081e1f5ab25f72dda95ecb2fb..a854ce54f67391a4c20ecc7bab96607f4af289f2 100644 (file)
@@ -147,12 +147,10 @@ def versioned_property(name, doc,
             deco = defaulting(deco)
         if generator != None:
             deco = cached(deco)
-        if default != None:
-            deco = defaulting(deco)
-        if allowed != None:
-            deco = checked(deco)
         if check_fn != None:
             deco = fn_checked(deco)
+        if allowed != None:
+            deco = checked(deco)
         return Property(deco)
     return decorator
 
@@ -220,6 +218,7 @@ class SavedSettingsObject(object):
 
 class SavedSettingsObjectTests(unittest.TestCase):
     def testSimpleProperty(self):
+        """Testing a minimal versioned property"""
         class Test(SavedSettingsObject):
             settings_properties = []
             required_saved_properties = []
@@ -277,6 +276,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
         self.failUnless(t.settings["Content-type"] == EMPTY,
                         t.settings["Content-type"])
     def testDefaultingProperty(self):
+        """Testing a defaulting versioned property"""
         class Test(SavedSettingsObject):
             settings_properties = []
             required_saved_properties = []
@@ -306,6 +306,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
         self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
                         t._get_saved_settings())
     def testRequiredDefaultingProperty(self):
+        """Testing a required defaulting versioned property"""
         class Test(SavedSettingsObject):
             settings_properties = []
             required_saved_properties = []
@@ -325,6 +326,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
         self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
                         t._get_saved_settings())
     def testClassVersionedPropertyDefinition(self):
+        """Testing a class-specific _versioned property decorator"""
         class Test(SavedSettingsObject):
             settings_properties = []
             required_saved_properties = []
@@ -349,6 +351,59 @@ class SavedSettingsObjectTests(unittest.TestCase):
         t.content_type = "text/html"
         self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
                         t._get_saved_settings())
+    def testMutableChangeHookedProperty(self):
+        """Testing a mutable change-hooked property"""
+        SAVES = []
+        def prop_log_save_settings(self, old, new, saves=SAVES):
+            saves.append("'%s' -> '%s'" % (str(old), str(new)))
+            prop_save_settings(self, old, new)
+        class Test(SavedSettingsObject):
+            settings_properties = []
+            required_saved_properties = []
+            @versioned_property(name="List-type",
+                                doc="A test property",
+                                mutable=True,
+                                change_hook=prop_log_save_settings,
+                                settings_properties=settings_properties,
+                                required_saved_properties=required_saved_properties)
+            def list_type(): return {}
+            def __init__(self):
+                SavedSettingsObject.__init__(self)
+        t = Test()
+        self.failUnless(t._settings_loaded == False, t._settings_loaded)
+        t.load_settings()
+        self.failUnless(SAVES == [], SAVES)
+        self.failUnless(t._settings_loaded == True, t._settings_loaded)
+        self.failUnless(t.list_type == EMPTY, t.list_type)
+        self.failUnless(SAVES == [
+                "'None' -> '<class 'libbe.settings_object.EMPTY'>'"
+                ], SAVES)
+        self.failUnless(t.settings["List-type"]==EMPTY,t.settings["List-type"])
+        t.list_type = []
+        self.failUnless(t.settings["List-type"] == [], t.settings["List-type"])
+        self.failUnless(SAVES == [
+                "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'"
+                ], SAVES)
+        t.list_type.append(5)
+        self.failUnless(SAVES == [
+                "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'" # <- TODO.  Where did this come from?
+                ], SAVES)
+        self.failUnless(t.settings["List-type"] == [5],t.settings["List-type"])
+        self.failUnless(SAVES == [ # the append(5) has not yet been saved
+                "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+                ], SAVES)
+        self.failUnless(t.list_type == [5], t.list_type) # <-get triggers saved
+        self.failUnless(SAVES == [ # now the append(5) has been saved.
+                "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+                "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+                "'[]' -> '[5]'"
+                ], SAVES)
 
 unitsuite=unittest.TestLoader().loadTestsFromTestCase(SavedSettingsObjectTests)
 suite = unittest.TestSuite([unitsuite, doctest.DocTestSuite()])