From 30eb2df6dfe46b772733c196350a9a7f2ec8dbe7 Mon Sep 17 00:00:00 2001 From: Stefan <96178532+stefan6419846@users.noreply.github.com> Date: Wed, 10 May 2023 12:27:25 +0200 Subject: [PATCH] Fix tests for Django 3.2 and Django 4.1 a (#166) Additionally updates the CI pipelines to run on Python up to 3.11. --- .github/workflows/ci.yml | 82 +++++++++----------------------- django_mock_queries/mocks.py | 9 ++-- django_mock_queries/utils.py | 3 +- examples/users/users/settings.py | 34 +++++-------- examples/users/users/urls.py | 4 +- requirements/dev.txt | 21 ++++---- setup.cfg | 2 +- tests/test_mocks.py | 9 +++- tests/test_utils.py | 2 +- tox.ini | 32 ++++++------- 10 files changed, 78 insertions(+), 120 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2802c19..a7847d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,70 +1,34 @@ name: CI on: - push: - branches: ['master', 'ci'] - pull_request: +- push +- pull_request jobs: main: strategy: matrix: include: - - python: '3.6' - tox_env: 'py36-dj111-drf37' - - - python: '3.6' - tox_env: 'py36-dj20-drf37' - - - python: '3.6' - tox_env: 'py36-dj21-drf37' - - - python: '3.6' - tox_env: 'py36-dj22-drf37' - - - python: '3.6' - tox_env: 'py36-dj111-drf39' - - - python: '3.6' - tox_env: 'py36-dj20-drf39' - - - python: '3.6' - tox_env: 'py36-dj21-drf39' - - - python: '3.6' - tox_env: 'py36-dj22-drf39' - - - python: '3.6' - tox_env: 'py36-dj30-drf310' - - - python: '3.7' - tox_env: 'py37-dj111-drf37' - - - python: '3.7' - tox_env: 'py37-dj20-drf37' - - - python: '3.7' - tox_env: 'py37-dj21-drf37' - - - python: '3.7' - tox_env: 'py37-dj22-drf37' - - - python: '3.7' - tox_env: 'py37-dj111-drf39' - - - python: '3.7' - tox_env: 'py37-dj20-drf39' - - - python: '3.7' - tox_env: 'py37-dj21-drf39' - - - python: '3.7' - tox_env: 'py37-dj22-drf39' - - - python: '3.7' - tox_env: 'py37-dj30-drf310' - - runs-on: ubuntu-20.04 + - python: '3.8' + tox_env: 'py38-dj22-drf313' + - python: '3.9' + tox_env: 'py39-dj22-drf313' + - python: '3.8' + tox_env: 'py38-dj32-drf314' + - python: '3.9' + tox_env: 'py39-dj32-drf314' + - python: '3.10' + tox_env: 'py310-dj32-drf314' + - python: '3.8' + tox_env: 'py38-dj41-drf314' + - python: '3.9' + tox_env: 'py39-dj41-drf314' + - python: '3.10' + tox_env: 'py310-dj41-drf314' + - python: '3.11' + tox_env: 'py311-dj41-drf314' + + runs-on: ubuntu-22.04 name: Python ${{ matrix.python }} with packages ${{ matrix.tox_env }} steps: - uses: actions/checkout@v3 @@ -75,7 +39,7 @@ jobs: python-version: ${{ matrix.python }} - name: install dependencies - run: python -m pip install "tox~=3.22.0" "coverage<4" "setuptools<40.0.0" + run: python -m pip install tox coverage - name: run test suite env: diff --git a/django_mock_queries/mocks.py b/django_mock_queries/mocks.py index 0e16153..a246f4e 100644 --- a/django_mock_queries/mocks.py +++ b/django_mock_queries/mocks.py @@ -88,7 +88,7 @@ def mock_django_connection(disabled_features=None): mock_ops = mock_connection.ops # noinspection PyUnusedLocal - def compiler(queryset, connection, using, **kwargs): + def compiler(queryset, using=None, connection=None, elide_empty=True, **kwargs): result = MagicMock(name='mock_connection.ops.compiler()') # noinspection PyProtectedMember result.execute_sql.side_effect = NotSupportedError( @@ -429,7 +429,7 @@ class ModelMocker(Mocker): default_methods = ['objects', '_do_update'] - if django.VERSION[0] == 3: + if django.VERSION[0] >= 3: default_methods += ['_base_manager._insert', ] else: default_methods += ['_meta.base_manager._insert', ] @@ -466,7 +466,10 @@ def _base_manager__insert(self, objects, *_, **__): obj = objects[0] self.objects.add(obj) - return [self._obj_pk(obj)] + # Do not set anything on the model instance itself, as we do not get any values from the database. + # The object ID is being set automatically. + # Reference: `django.db.models.base.Model._save_table` + return [] def _do_update(self, *args, **_): _, _, pk_val, values, _, _ = args diff --git a/django_mock_queries/utils.py b/django_mock_queries/utils.py index 9a03480..ad9ab00 100644 --- a/django_mock_queries/utils.py +++ b/django_mock_queries/utils.py @@ -128,8 +128,7 @@ def get_attribute(obj, attr, default=None): def is_match(first, second, comparison=None): if isinstance(first, django_mock_queries.query.MockSet): return is_match_in_children(comparison, first, second) - if (isinstance(first, (int, str)) and - isinstance(second, django_mock_queries.query.MockSet)): + if (isinstance(first, (int, str)) and isinstance(second, django_mock_queries.query.MockSet)): second = convert_to_pks(second) if (isinstance(first, date) or isinstance(first, datetime)) \ and isinstance(comparison, tuple) and len(comparison) == 2: diff --git a/examples/users/users/settings.py b/examples/users/users/settings.py index f740fa2..9689000 100644 --- a/examples/users/users/settings.py +++ b/examples/users/users/settings.py @@ -41,27 +41,16 @@ 'analytics', ) -if django.VERSION[0] == 1: - MIDDLEWARE_CLASSES = ( - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.security.SecurityMiddleware', - ) -else: - MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - ] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] ROOT_URLCONF = 'users.urls' @@ -104,7 +93,8 @@ USE_I18N = True -USE_L10N = True +if django.VERSION[0] < 5: + USE_L10N = True USE_TZ = True diff --git a/examples/users/users/urls.py b/examples/users/users/urls.py index a46b2f8..8c42d9b 100644 --- a/examples/users/users/urls.py +++ b/examples/users/users/urls.py @@ -13,10 +13,10 @@ 1. Add an import: from blog import urls as blog_urls 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) """ -from django.conf.urls import url +from django.urls import re_path from analytics import views urlpatterns = [ - url(r'users/active', views.active_users), + re_path(r'users/active', views.active_users), ] diff --git a/requirements/dev.txt b/requirements/dev.txt index 20eab73..7a77d89 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,11 +1,10 @@ -pytest==4.6.11 -pytest-cov==2.4.0 -pytest-flake8==0.7 -pytest-django==3.1.2 -flake8==3.4.1 -coverage==3.7.1 -tox==3.10.0 -virtualenv==14.0.6 -pypandoc==1.4 -setuptools==39.2.0 -twine==1.11.0 +pytest==7.3.1 +pytest-cov==4.0.0 +pytest-django +flake8==6.0.0 +coverage==7.2.5 +tox==4.5.1 +virtualenv==20.23.0 +pypandoc==1.11 +setuptools==67.7.2 +twine==4.0.2 diff --git a/setup.cfg b/setup.cfg index fe62be2..5b85a0f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [metadata] -description-file = README.md +description_file = README.md [bdist_wheel] universal = 1 diff --git a/tests/test_mocks.py b/tests/test_mocks.py index adbd0b6..bab0b12 100644 --- a/tests/test_mocks.py +++ b/tests/test_mocks.py @@ -103,7 +103,7 @@ def test_delegation(self): # noinspection PyUnresolvedReferences,PyStatementEffect class MockOneToManyTests(TestCase): def test_not_mocked(self): - m = Manufacturer() + m = Manufacturer(id=99) with self.assertRaisesRegex( NotSupportedError, @@ -111,7 +111,7 @@ def test_not_mocked(self): m.car_set.count() def test_mock_is_removed(self): - m = Manufacturer() + m = Manufacturer(id=99) with patch.object(Manufacturer, 'car_set', MockOneToManyMap(Manufacturer.car_set)): m.car_set = MockSet(Car(speed=95)) @@ -412,6 +412,11 @@ def test_model_mocker_instance_save(self): obj.save() self.assertEqual(Car.objects.get(pk=obj.id), obj) + # Another instances gets inserted and has a different ID + obj2 = Car(speed=5) + obj.save() + self.assertNotEqual(obj.id, obj2.id) + # Existing instance gets updated obj = Car(id=obj.id, speed=5) obj.save() diff --git a/tests/test_utils.py b/tests/test_utils.py index b1ea250..4d9483d 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -82,7 +82,7 @@ def test_get_attribute_returns_tuple_with_exact_as_default_comparison(self): assert comparison == (constants.COMPARISON_YEAR, constants.COMPARISON_EXACT) def test_validate_date_or_datetime_raises_value_error(self): - with self.assertRaisesRegexp(ValueError, r'13 is incorrect value for month'): + with self.assertRaisesRegex(ValueError, r'13 is incorrect value for month'): utils.validate_date_or_datetime(13, constants.COMPARISON_MONTH) def test_is_match_equality_check_when_comparison_none(self): diff --git a/tox.ini b/tox.ini index 8316acc..bd92473 100644 --- a/tox.ini +++ b/tox.ini @@ -1,34 +1,32 @@ [tox] -# See https://docs.djangoproject.com/en/2.0/faq/install/#what-python-version-can-i-use-with-django +# See https://docs.djangoproject.com/en/4.1/faq/install/#what-python-version-can-i-use-with-django envlist = - py{36,37}-dj{111}-drf{37,39} - py{36,37}-dj{20,21,22}-drf{37,39} - py{36,37}-dj{30}-drf{310} -requires = virtualenv >= 20.0 + py{38,39}-dj22-drf{311,313} + py{38,39,310}-dj32-drf{314} + py{38,39,310,311}-dj41-drf{314} [pytest] norecursedirs = examples [flake8] -ignore = *.py F403 F405 E731 +ignore = F403 F405 E731 max-line-length = 120 [testenv] download = true -setenv = - VIRTUALENV_PIP=20.2.3 - VIRTUALENV_DOWNLOAD=1 +constrain_package_deps = true +use_frozen_constraints = false deps = -rrequirements/dev.txt - dj111: Django~=1.11.17 - dj20: Django~=2.0.2 - dj21: Django~=2.1.0 dj22: Django~=2.2.1 - dj30: Django~=3.0.3 - drf33: djangorestframework~=3.3.2 - drf37: djangorestframework~=3.7.7 - drf39: djangorestframework~=3.9.2 - drf310: djangorestframework~=3.10.3 + dj22: pytest-django~=4.5.2 + dj32: Django~=3.2.0 + dj32: pytest-django~=4.5.2 + dj41: Django~=4.1.7 + dj41: pytest-django~=4.5.2 + drf311: djangorestframework~=3.11.2 + drf313: djangorestframework~=3.13.1 + drf314: djangorestframework~=3.14.0 commands = pytest django_mock_queries/ tests/ --cov-report term-missing --cov=django_mock_queries