Commits

Jean-Tiare Le Bigot committed 059791c

End transaction rework.

bump version number to 1.6
tested against real world transaction (WW)
fixed nasty bug causing transactions/save to always fail when item contains a bool field set to false.
added regression tests for this bug + inline doc on the fix

  • Participants
  • Parent commits fd0eac0

Comments (0)

Files changed (3)

File dynamodb_mapper/model.py

             default = default()
         # Check default value consitency
         if not isinstance(default, schema_type):
-            raise TypeError("Expected default value of type {}, got: {}".format(schema_type.__name__, default.__class__.__name__))
+            raise TypeError("Expected default value of type {}, got: {}".format(schema_type, type(default)))
         else:
             return default
 
         s = s[:-2] + ':' + s[-2:]
         return s
 
+    # This case prevents `'fields': False` to be added when genereating expected
+    # values dict in save as this would mean 'field does not exist' instead of
+    # 'field exists and is False'.
+    if isinstance(value, bool):
+        return 1 if value else 0
+
     if value or value == 0:
         return value
 

File dynamodb_mapper/tests/test_model.py

     }
 
 
+# boolean regression test
+class DoomCampaignStatus(DynamoDBModel):
+    __table__ = "doom_campaign_status"
+    __hash_key__ = "id"
+    __schema__ = {
+        "id": int,
+        "name": unicode,
+        "completed": bool,
+    }
+
 # list attribute
 class DoomMonster(DynamoDBModel):
     __table__ = "doom_monster"
         self.assertEquals(0.0, _python_to_dynamodb(0.0))
         self.assertEquals(10, _python_to_dynamodb(10))
         self.assertEquals(10.0, _python_to_dynamodb(10.0))
+        self.assertEquals(0, _python_to_dynamodb(False))
+        self.assertEquals(1, _python_to_dynamodb(True))
 
     def test_dynamodb_to_python_number(self):
         self.assertEquals(0, _dynamodb_to_python(int, 0))
         self.assertEquals(0.0, _dynamodb_to_python(float, 0.0))
         self.assertEquals(10, _dynamodb_to_python(int, 10))
         self.assertEquals(10.0, _dynamodb_to_python(float, 10.0))
+        self.assertEquals(False, _dynamodb_to_python(bool, 0))
+        self.assertEquals(True, _dynamodb_to_python(bool, 1))
 
     def test_python_to_dynamodb_unicode(self):
         self.assertEquals(u"hello", _python_to_dynamodb(u"hello"))
         c.save(expected_values={"id": 1, "name": name, "cheats": cheats})
         m_item_instance.put.assert_called_with({"id": 1, "name": name, "cheats": cheats})
 
+
+    @mock.patch("dynamodb_mapper.model.Item")
+    @mock.patch("dynamodb_mapper.model.boto")
+    def test_save_expected_values_boolean(self, m_boto, m_item):
+        m_item_instance = m_item.return_value
+
+        name = "Knee-deep in the Dead"
+        completed = False
+
+        c = DoomCampaignStatus()
+        c.id = 0
+        c.name = name
+        c.completed = completed
+
+        c.save(expected_values={"id": 1, "name": name, "completed": completed})
+        m_item_instance.put.assert_called_with({"id": 1, "name": name, "completed": 0})
+
     @mock.patch("dynamodb_mapper.model.Item")
     @mock.patch("dynamodb_mapper.model.boto")
     def test_save_no_overwrite_composite_fails(self, m_boto, m_item):
 [metadata]
 name = dynamodb-mapper
-version = 1.5.0
+version = 1.6.0
 summary = Object mapper for Amazon DynamoDB
 description_file = README.rst
 author = Max Noel
-author_email = mnoel@ludia.com
+author_email = mnoel@ludia.com, jtlebigot@ludia.com
 classifiers =
     License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
 requires-dist =