1 2from south.tests import Monkeypatcher, skipUnless 3from south.modelsinspector import (convert_on_delete_handler, get_value, 4 IsDefault, models, value_clean) 5 6from fakeapp.models import HorribleModel, get_sentinel_object 7 8 9on_delete_is_available = hasattr(models, "PROTECT") # models here is django.db.models 10skipUnlessOnDeleteAvailable = skipUnless(on_delete_is_available, "not testing on_delete -- not available on Django<1.3") 11 12class TestModelInspector(Monkeypatcher): 13 14 """ 15 Tests if the various parts of the modelinspector work. 16 """ 17 18 def test_get_value(self): 19 20 # Let's start nicely. 21 name = HorribleModel._meta.get_field_by_name("name")[0] 22 slug = HorribleModel._meta.get_field_by_name("slug")[0] 23 user = HorribleModel._meta.get_field_by_name("user")[0] 24 25 # Simple int retrieval 26 self.assertEqual( 27 get_value(name, ["max_length", {}]), 28 "255", 29 ) 30 31 # Bool retrieval 32 self.assertEqual( 33 get_value(slug, ["unique", {}]), 34 "True", 35 ) 36 37 # String retrieval 38 self.assertEqual( 39 get_value(user, ["rel.related_name", {}]), 40 "'horribles'", 41 ) 42 43 # Default triggering 44 self.assertEqual( 45 get_value(slug, ["unique", {"default": False}]), 46 "True", 47 ) 48 self.assertRaises( 49 IsDefault, 50 get_value, 51 slug, 52 ["unique", {"default": True}], 53 ) 54 55 @skipUnlessOnDeleteAvailable 56 def test_get_value_on_delete(self): 57 58 # First validate the FK fields with on_delete options 59 o_set_null_on_delete = HorribleModel._meta.get_field_by_name("o_set_null_on_delete")[0] 60 o_cascade_delete = HorribleModel._meta.get_field_by_name("o_cascade_delete")[0] 61 o_protect = HorribleModel._meta.get_field_by_name("o_protect")[0] 62 o_default_on_delete = HorribleModel._meta.get_field_by_name("o_default_on_delete")[0] 63 o_set_on_delete_function = HorribleModel._meta.get_field_by_name("o_set_on_delete_function")[0] 64 o_set_on_delete_value = HorribleModel._meta.get_field_by_name("o_set_on_delete_value")[0] 65 o_no_action_on_delete = HorribleModel._meta.get_field_by_name("o_no_action_on_delete")[0] 66 # TODO this is repeated from the introspection_details in modelsinspector: 67 # better to refactor that so we can reference these settings, in case they 68 # must change at some point. 69 on_delete = ["rel.on_delete", {"default": models.CASCADE, "is_django_function": True, "converter": convert_on_delete_handler, }] 70 71 # Foreign Key cascade update/delete 72 self.assertRaises( 73 IsDefault, 74 get_value, 75 o_cascade_delete, 76 on_delete, 77 ) 78 self.assertEqual( 79 get_value(o_protect, on_delete), 80 "models.PROTECT", 81 ) 82 self.assertEqual( 83 get_value(o_no_action_on_delete, on_delete), 84 "models.DO_NOTHING", 85 ) 86 self.assertEqual( 87 get_value(o_set_null_on_delete, on_delete), 88 "models.SET_NULL", 89 ) 90 self.assertEqual( 91 get_value(o_default_on_delete, on_delete), 92 "models.SET_DEFAULT", 93 ) 94 # For now o_set_on_delete raises, see modelsinspector.py 95 #self.assertEqual( 96 # get_value(o_set_on_delete_function, on_delete), 97 # "models.SET(get_sentinel_object)", 98 #) 99 self.assertRaises( 100 ValueError, 101 get_value, 102 o_set_on_delete_function, 103 on_delete, 104 ) 105 self.assertEqual( 106 get_value(o_set_on_delete_value, on_delete), 107 "models.SET(%s)" % value_clean(get_sentinel_object()), 108 ) 109