/tests/regressiontests/introspection/tests.py
Python | 111 lines | 77 code | 17 blank | 17 comment | 16 complexity | fbb47eace4f3a38331c8047234f7f256 MD5 | raw file
Possible License(s): BSD-3-Clause
1from django.conf import settings 2from django.db import connection, DEFAULT_DB_ALIAS 3from django.test import TestCase, skipUnlessDBFeature 4from django.utils import functional 5 6from models import Reporter, Article 7 8# 9# The introspection module is optional, so methods tested here might raise 10# NotImplementedError. This is perfectly acceptable behavior for the backend 11# in question, but the tests need to handle this without failing. Ideally we'd 12# skip these tests, but until #4788 is done we'll just ignore them. 13# 14# The easiest way to accomplish this is to decorate every test case with a 15# wrapper that ignores the exception. 16# 17# The metaclass is just for fun. 18# 19 20def ignore_not_implemented(func): 21 def _inner(*args, **kwargs): 22 try: 23 return func(*args, **kwargs) 24 except NotImplementedError: 25 return None 26 functional.update_wrapper(_inner, func) 27 return _inner 28 29class IgnoreNotimplementedError(type): 30 def __new__(cls, name, bases, attrs): 31 for k,v in attrs.items(): 32 if k.startswith('test'): 33 attrs[k] = ignore_not_implemented(v) 34 return type.__new__(cls, name, bases, attrs) 35 36class IntrospectionTests(TestCase): 37 __metaclass__ = IgnoreNotimplementedError 38 39 def test_table_names(self): 40 tl = connection.introspection.table_names() 41 self.assertTrue(Reporter._meta.db_table in tl, 42 "'%s' isn't in table_list()." % Reporter._meta.db_table) 43 self.assertTrue(Article._meta.db_table in tl, 44 "'%s' isn't in table_list()." % Article._meta.db_table) 45 46 def test_django_table_names(self): 47 cursor = connection.cursor() 48 cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);'); 49 tl = connection.introspection.django_table_names() 50 cursor.execute("DROP TABLE django_ixn_test_table;") 51 self.assertTrue('django_ixn_testcase_table' not in tl, 52 "django_table_names() returned a non-Django table") 53 54 def test_installed_models(self): 55 tables = [Article._meta.db_table, Reporter._meta.db_table] 56 models = connection.introspection.installed_models(tables) 57 self.assertEqual(models, set([Article, Reporter])) 58 59 def test_sequence_list(self): 60 sequences = connection.introspection.sequence_list() 61 expected = {'table': Reporter._meta.db_table, 'column': 'id'} 62 self.assertTrue(expected in sequences, 63 'Reporter sequence not found in sequence_list()') 64 65 def test_get_table_description_names(self): 66 cursor = connection.cursor() 67 desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) 68 self.assertEqual([r[0] for r in desc], 69 [f.column for f in Reporter._meta.fields]) 70 71 def test_get_table_description_types(self): 72 cursor = connection.cursor() 73 desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) 74 self.assertEqual( 75 [datatype(r[1], r) for r in desc], 76 ['IntegerField', 'CharField', 'CharField', 'CharField', 'BigIntegerField'] 77 ) 78 79 # Regression test for #9991 - 'real' types in postgres 80 @skipUnlessDBFeature('has_real_datatype') 81 def test_postgresql_real_type(self): 82 cursor = connection.cursor() 83 cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);") 84 desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table') 85 cursor.execute('DROP TABLE django_ixn_real_test_table;') 86 self.assertEqual(datatype(desc[0][1], desc[0]), 'FloatField') 87 88 def test_get_relations(self): 89 cursor = connection.cursor() 90 relations = connection.introspection.get_relations(cursor, Article._meta.db_table) 91 92 # Older versions of MySQL don't have the chops to report on this stuff, 93 # so just skip it if no relations come back. If they do, though, we 94 # should test that the response is correct. 95 if relations: 96 # That's {field_index: (field_index_other_table, other_table)} 97 self.assertEqual(relations, {3: (0, Reporter._meta.db_table)}) 98 99 def test_get_indexes(self): 100 cursor = connection.cursor() 101 indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) 102 self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False}) 103 104 105def datatype(dbtype, description): 106 """Helper to convert a data type into a string.""" 107 dt = connection.introspection.get_field_type(dbtype, description) 108 if type(dt) is tuple: 109 return dt[0] 110 else: 111 return dt