summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorNick Pope <nick.pope@flightdataservices.com>2019-07-26 22:05:22 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-08-02 11:39:01 +0200
commit194d1dfc186cc8d2b35dabf64f3ed38b757cbd98 (patch)
tree51ffabb34edc5b191ce8079c9149b77c88c2749e /tests
parent955b382600e4626265cc20e5773bdbcfd01fc4af (diff)
Fixed #30661 -- Added models.SmallAutoField.
Diffstat (limited to 'tests')
-rw-r--r--tests/db_functions/comparison/test_cast.py1
-rw-r--r--tests/introspection/models.py5
-rw-r--r--tests/introspection/tests.py13
-rw-r--r--tests/many_to_one/models.py6
-rw-r--r--tests/many_to_one/tests.py14
-rw-r--r--tests/migrations/test_operations.py48
-rw-r--r--tests/schema/tests.py47
7 files changed, 120 insertions, 14 deletions
diff --git a/tests/db_functions/comparison/test_cast.py b/tests/db_functions/comparison/test_cast.py
index c5698d6d0e..988eaa4dad 100644
--- a/tests/db_functions/comparison/test_cast.py
+++ b/tests/db_functions/comparison/test_cast.py
@@ -55,6 +55,7 @@ class CastTests(TestCase):
for field_class in (
models.AutoField,
models.BigAutoField,
+ models.SmallAutoField,
models.IntegerField,
models.BigIntegerField,
models.SmallIntegerField,
diff --git a/tests/introspection/models.py b/tests/introspection/models.py
index fa663de2fd..d069c5820e 100644
--- a/tests/introspection/models.py
+++ b/tests/introspection/models.py
@@ -9,6 +9,11 @@ class City(models.Model):
return self.name
+class Country(models.Model):
+ id = models.SmallAutoField(primary_key=True)
+ name = models.CharField(max_length=50)
+
+
class District(models.Model):
city = models.ForeignKey(City, models.CASCADE, primary_key=True)
name = models.CharField(max_length=50)
diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py
index 7edb01a4b7..4a7ce11e7a 100644
--- a/tests/introspection/tests.py
+++ b/tests/introspection/tests.py
@@ -5,7 +5,9 @@ from django.db.models import Index
from django.db.utils import DatabaseError
from django.test import TransactionTestCase, skipUnlessDBFeature
-from .models import Article, ArticleReporter, City, Comment, District, Reporter
+from .models import (
+ Article, ArticleReporter, City, Comment, Country, District, Reporter,
+)
class IntrospectionTests(TransactionTestCase):
@@ -115,6 +117,15 @@ class IntrospectionTests(TransactionTestCase):
[connection.introspection.get_field_type(r[1], r) for r in desc],
)
+ @skipUnlessDBFeature('can_introspect_autofield')
+ def test_smallautofield(self):
+ with connection.cursor() as cursor:
+ desc = connection.introspection.get_table_description(cursor, Country._meta.db_table)
+ self.assertIn(
+ connection.features.introspected_small_auto_field_type,
+ [connection.introspection.get_field_type(r[1], r) for r in desc],
+ )
+
# Regression test for #9991 - 'real' types in postgres
@skipUnlessDBFeature('has_real_datatype')
def test_postgresql_real_type(self):
diff --git a/tests/many_to_one/models.py b/tests/many_to_one/models.py
index 6230129bbd..6e00fb18fa 100644
--- a/tests/many_to_one/models.py
+++ b/tests/many_to_one/models.py
@@ -27,8 +27,14 @@ class Article(models.Model):
return self.headline
+class Country(models.Model):
+ id = models.SmallAutoField(primary_key=True)
+ name = models.CharField(max_length=50)
+
+
class City(models.Model):
id = models.BigAutoField(primary_key=True)
+ country = models.ForeignKey(Country, models.CASCADE, related_name='cities', null=True)
name = models.CharField(max_length=50)
def __str__(self):
diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py
index e3121a7701..a926574b15 100644
--- a/tests/many_to_one/tests.py
+++ b/tests/many_to_one/tests.py
@@ -8,8 +8,9 @@ from django.test import TestCase
from django.utils.translation import gettext_lazy
from .models import (
- Article, Category, Child, ChildNullableParent, City, District, First,
- Parent, Record, Relation, Reporter, School, Student, Third, ToFieldChild,
+ Article, Category, Child, ChildNullableParent, City, Country, District,
+ First, Parent, Record, Relation, Reporter, School, Student, Third,
+ ToFieldChild,
)
@@ -576,6 +577,15 @@ class ManyToOneTests(TestCase):
District.objects.create(city=ny, name='Brooklyn')
District.objects.create(city=ny, name='Manhattan')
+ def test_fk_to_smallautofield(self):
+ us = Country.objects.create(name='United States')
+ City.objects.create(country=us, name='Chicago')
+ City.objects.create(country=us, name='New York')
+
+ uk = Country.objects.create(name='United Kingdom', id=2 ** 11)
+ City.objects.create(country=uk, name='London')
+ City.objects.create(country=uk, name='Edinburgh')
+
def test_multiple_foreignkeys(self):
# Test of multiple ForeignKeys to the same model (bug #7125).
c1 = Category.objects.create(name='First')
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 3b2129a933..3c321d4cb4 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -2651,9 +2651,13 @@ class OperationTests(OperationTestBase):
fill_data.state_forwards("fill_data", new_state)
fill_data.database_forwards("fill_data", editor, project_state, new_state)
- def test_autofield_foreignfield_growth(self):
+ def _test_autofield_foreignfield_growth(self, source_field, target_field, target_value):
"""
- A field may be migrated from AutoField to BigAutoField.
+ A field may be migrated in the following ways:
+
+ - AutoField to BigAutoField
+ - SmallAutoField to AutoField
+ - SmallAutoField to BigAutoField
"""
def create_initial_data(models, schema_editor):
Article = models.get_model("test_article", "Article")
@@ -2665,14 +2669,14 @@ class OperationTests(OperationTestBase):
def create_big_data(models, schema_editor):
Article = models.get_model("test_article", "Article")
Blog = models.get_model("test_blog", "Blog")
- blog2 = Blog.objects.create(name="Frameworks", id=2 ** 33)
+ blog2 = Blog.objects.create(name="Frameworks", id=target_value)
Article.objects.create(name="Django", blog=blog2)
- Article.objects.create(id=2 ** 33, name="Django2", blog=blog2)
+ Article.objects.create(id=target_value, name="Django2", blog=blog2)
create_blog = migrations.CreateModel(
"Blog",
[
- ("id", models.AutoField(primary_key=True)),
+ ("id", source_field(primary_key=True)),
("name", models.CharField(max_length=100)),
],
options={},
@@ -2680,7 +2684,7 @@ class OperationTests(OperationTestBase):
create_article = migrations.CreateModel(
"Article",
[
- ("id", models.AutoField(primary_key=True)),
+ ("id", source_field(primary_key=True)),
("blog", models.ForeignKey(to="test_blog.Blog", on_delete=models.CASCADE)),
("name", models.CharField(max_length=100)),
("data", models.TextField(default="")),
@@ -2690,8 +2694,8 @@ class OperationTests(OperationTestBase):
fill_initial_data = migrations.RunPython(create_initial_data, create_initial_data)
fill_big_data = migrations.RunPython(create_big_data, create_big_data)
- grow_article_id = migrations.AlterField("Article", "id", models.BigAutoField(primary_key=True))
- grow_blog_id = migrations.AlterField("Blog", "id", models.BigAutoField(primary_key=True))
+ grow_article_id = migrations.AlterField('Article', 'id', target_field(primary_key=True))
+ grow_blog_id = migrations.AlterField('Blog', 'id', target_field(primary_key=True))
project_state = ProjectState()
new_state = project_state.clone()
@@ -2719,7 +2723,7 @@ class OperationTests(OperationTestBase):
state = new_state.clone()
article = state.apps.get_model("test_article.Article")
- self.assertIsInstance(article._meta.pk, models.BigAutoField)
+ self.assertIsInstance(article._meta.pk, target_field)
project_state = new_state
new_state = new_state.clone()
@@ -2729,7 +2733,7 @@ class OperationTests(OperationTestBase):
state = new_state.clone()
blog = state.apps.get_model("test_blog.Blog")
- self.assertIsInstance(blog._meta.pk, models.BigAutoField)
+ self.assertIsInstance(blog._meta.pk, target_field)
project_state = new_state
new_state = new_state.clone()
@@ -2737,6 +2741,30 @@ class OperationTests(OperationTestBase):
fill_big_data.state_forwards("fill_big_data", new_state)
fill_big_data.database_forwards("fill_big_data", editor, project_state, new_state)
+ def test_autofield__bigautofield_foreignfield_growth(self):
+ """A field may be migrated from AutoField to BigAutoField."""
+ self._test_autofield_foreignfield_growth(
+ models.AutoField,
+ models.BigAutoField,
+ 2 ** 33,
+ )
+
+ def test_smallfield_autofield_foreignfield_growth(self):
+ """A field may be migrated from SmallAutoField to AutoField."""
+ self._test_autofield_foreignfield_growth(
+ models.SmallAutoField,
+ models.AutoField,
+ 2 ** 22,
+ )
+
+ def test_smallfield_bigautofield_foreignfield_growth(self):
+ """A field may be migrated from SmallAutoField to BigAutoField."""
+ self._test_autofield_foreignfield_growth(
+ models.SmallAutoField,
+ models.BigAutoField,
+ 2 ** 33,
+ )
+
def test_run_python_noop(self):
"""
#24098 - Tests no-op RunPython operations.
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index a765528d50..7276912c71 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -14,7 +14,8 @@ from django.db.models.deletion import CASCADE, PROTECT
from django.db.models.fields import (
AutoField, BigAutoField, BigIntegerField, BinaryField, BooleanField,
CharField, DateField, DateTimeField, IntegerField, PositiveIntegerField,
- SlugField, TextField, TimeField, UUIDField,
+ SlugField, SmallAutoField, SmallIntegerField, TextField, TimeField,
+ UUIDField,
)
from django.db.models.fields.related import (
ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
@@ -1179,6 +1180,28 @@ class SchemaTests(TransactionTestCase):
# Fail on PostgreSQL if sequence is missing an owner.
self.assertIsNotNone(Author.objects.create(name='Bar'))
+ def test_alter_autofield_pk_to_smallautofield_pk_sequence_owner(self):
+ """
+ Converting an implicit PK to SmallAutoField(primary_key=True) should
+ keep a sequence owner on PostgreSQL.
+ """
+ with connection.schema_editor() as editor:
+ editor.create_model(Author)
+ old_field = Author._meta.get_field('id')
+ new_field = SmallAutoField(primary_key=True)
+ new_field.set_attributes_from_name('id')
+ new_field.model = Author
+ with connection.schema_editor() as editor:
+ editor.alter_field(Author, old_field, new_field, strict=True)
+
+ Author.objects.create(name='Foo', pk=1)
+ with connection.cursor() as cursor:
+ sequence_reset_sqls = connection.ops.sequence_reset_sql(no_style(), [Author])
+ if sequence_reset_sqls:
+ cursor.execute(sequence_reset_sqls[0])
+ # Fail on PostgreSQL if sequence is missing an owner.
+ self.assertIsNotNone(Author.objects.create(name='Bar'))
+
def test_alter_int_pk_to_autofield_pk(self):
"""
Should be able to rename an IntegerField(primary_key=True) to
@@ -1211,6 +1234,28 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(IntegerPK, old_field, new_field, strict=True)
+ @isolate_apps('schema')
+ def test_alter_smallint_pk_to_smallautofield_pk(self):
+ """
+ Should be able to rename an SmallIntegerField(primary_key=True) to
+ SmallAutoField(primary_key=True).
+ """
+ class SmallIntegerPK(Model):
+ i = SmallIntegerField(primary_key=True)
+
+ class Meta:
+ app_label = 'schema'
+
+ with connection.schema_editor() as editor:
+ editor.create_model(SmallIntegerPK)
+ self.isolated_local_models = [SmallIntegerPK]
+ old_field = SmallIntegerPK._meta.get_field('i')
+ new_field = SmallAutoField(primary_key=True)
+ new_field.model = SmallIntegerPK
+ new_field.set_attributes_from_name('i')
+ with connection.schema_editor() as editor:
+ editor.alter_field(SmallIntegerPK, old_field, new_field, strict=True)
+
def test_alter_int_pk_to_int_unique(self):
"""
Should be able to rename an IntegerField(primary_key=True) to