Commits

Jean-Tiare Le Bigot committed 06184bf

add tests for onctuous integration. /me starts to fear documentation for this

  • Participants
  • Parent commits e601568

Comments (0)

Files changed (2)

dynamodb_mapper/model.py

     schema_type = type(schema_entry)
 
     # Handle json related type
-    if schema_entry in _JSON_TYPES:
-        # basic type => just load it and return
-        if value is None:
-            return schema_entry()
-        return schema_entry(json.loads(value))
-    elif schema_type in _JSON_TYPES:
+    if schema_type in _JSON_TYPES:
         # looks like a validator => load and validate it
         if value is None:
             value = schema_type()
         else:
             value = schema_type(json.loads(value))
         return Schema(schema_entry)(value)
+    elif schema_entry in _JSON_TYPES:
+        # basic type => just load it and return
+        if value is None:
+            return schema_entry()
+        return schema_entry(json.loads(value))
 
     # Handle this f** datetime sh** (sorry for expressing my thougts aloud)
     # if we enter this, it means this is not a validator so return directly

dynamodb_mapper/tests/test_model.py

-import unittest
-
-import json
-
-import mock
+import unittest, mock
 
 from dynamodb_mapper.model import (ConnectionBorg, DynamoDBModel,
     autoincrement_int, MaxRetriesExceededError, MAX_RETRIES,
     SchemaError, MAGIC_KEY, OverwriteError, InvalidRegionError,)
 from boto.exception import DynamoDBResponseError
 from boto.dynamodb.exceptions import DynamoDBConditionalCheckFailedError
-import datetime
+from onctuous.validators import InRange, All, Length, Coerce
+from onctuous.errors import Invalid
+
+import json, datetime
 
 class mocked_region(object):
     def __init__(self, name):
     }
 
 
+class SchemaValidators(DynamoDBModel):
+    __table__ = "SchemaValidators"
+    __hash_key__ = "name"
+    __schema__ = {
+        "name": All(Coerce(unicode), Length(min=3, max=15)),
+        "age": InRange(min=0),
+        "scores": [InRange(min=0, max=100)],
+    }
+
+class SchemaValidatorsBad(DynamoDBModel):
+    __table__ = "SchemaValidatorsBad"
+    __hash_key__ = "name"
+    __schema__ = {
+        "name": unicode,
+        "bad": set([1,2,3]),
+    }
+
 class TestUTC(unittest.TestCase):
     def test_utcoffset(self):
         self.assertEqual(datetime.timedelta(0), UTC().utcoffset(None))
     def test_dst(self):
         self.assertEqual(datetime.timedelta(0), UTC().dst(None))
 
+
 class TestConnectionBorg(unittest.TestCase):
     def setUp(self):
         ConnectionBorg._shared_state = {
         self.assertIs(None, borg1._region)
         self.assertIs(None, borg2._region)
 
-
     @mock.patch("dynamodb_mapper.model.boto")
     def test_set_credentials(self, m_boto):
         # Make sure internal state is set and shared
 
         table.refresh.assert_called_once_with(wait_for_active=True)
 
+    @mock.patch("dynamodb_mapper.model.boto")
+    def test_create_table_validators(self, m_boto):
+        m_connection = m_boto.connect_dynamodb.return_value
+        m_create_schema = m_connection.create_schema
+        m_create_table = m_connection.create_table
+
+        table = ConnectionBorg().create_table(SchemaValidators, 10, 5, True)
+
+        m_create_schema.assert_called_once_with(
+            hash_key_name=SchemaValidators.__hash_key__,
+            hash_key_proto_value=u"",
+            range_key_name=None,
+            range_key_proto_value=None,
+        )
+
+        m_create_table.assert_called_once_with(
+            SchemaValidators.__table__, m_create_schema.return_value, 10, 5)
+
+        table.refresh.assert_called_once_with(wait_for_active=True)
+
 
 class TestTypeConversions(unittest.TestCase):
     def test_python_to_dynamodb_number(self):
         e2 = DoomMonsterMap._from_db_dict({"map_id": 1})
         self.assertEqual(e2.monsters, {})
 
+    def test_build_from_db_dict_validators(self):
+        scores = [1,2,3,4]
+
+        # nominal test
+        raw_dict = {
+            "name": u"Jean-Tiare",
+            "age": 22,
+            "scores": json.dumps(scores, sort_keys=True)
+        }
+
+        e = SchemaValidators._from_db_dict(raw_dict)
+        self.assertEqual(u"Jean-Tiare", e.name)
+        self.assertEqual(22, e.age)
+        self.assertEqual(scores, e.scores)
+
+        # empty scores
+        raw_dict = {
+            "name": u"Jean-Tiare",
+            "age": 22,
+        }
+
+        e = SchemaValidators._from_db_dict(raw_dict)
+        self.assertEqual(u"Jean-Tiare", e.name)
+        self.assertEqual(22, e.age)
+        self.assertEqual([], e.scores)
+
+        # bad age
+        raw_dict = {
+            "name": u"Jean-Tiare",
+            "age": -1,
+            "scores": json.dumps(scores, sort_keys=True)
+        }
+        self.assertRaises(Invalid, SchemaValidators._from_db_dict, raw_dict)
+
+        # bad score
+        raw_dict = {
+            "name": u"Jean-Tiare",
+            "age": 22,
+            "scores": json.dumps([101], sort_keys=True)
+        }
+        self.assertRaises(Invalid, SchemaValidators._from_db_dict, raw_dict)
+
+    def test_from_db_dict_validators_bad(self):
+        # unsupported specification in schema
+        raw_dict = {
+            "name": u"Jean-Tiare",
+        }
+
+        self.assertRaises(SchemaError, SchemaValidatorsBad._from_db_dict, raw_dict)
+
     def test_to_db_dict_json_list(self):
         #FIXME: can it be removed as this feature is implicitly tested elsewhere ?
         attacks = [
         self.assertEqual(d["map_id"], 1)
         self.assertEqual(d["monsters"], json.dumps(monsters, sort_keys=True))
 
+    def test_to_db_dict_validators(self):
+        e = SchemaValidators()
+        e.name = u"Jean-Tiare"
+        e.age = 22
+        e.scores = [1,2,3,4]
+
+        d = e._to_db_dict()
+
+
+        self.assertEqual(d[u"name"], e.name)
+        self.assertEqual(d[u"age"], e.age)
+        self.assertEqual(d[u"scores"], json.dumps(e.scores))
+
     @mock.patch("dynamodb_mapper.model.Item")
     @mock.patch("dynamodb_mapper.model.boto")
     def test_save_simple_types(self, m_boto, m_item):