diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..f5e7178 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,84 @@ +# copied from django-cte +name: entity_event tests +on: + push: + branches: [master] + pull_request: + branches: [master,develop] + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python: ['3.7', '3.8', '3.9'] + # Time to switch to pytest or nose2?? + # nosetests is broken on 3.10 + # AttributeError: module 'collections' has no attribute 'Callable' + # https://github.com/nose-devs/nose/issues/1099 + django: + - 'Django~=2.2.0' + - 'Django~=3.0.0' + - 'Django~=3.1.0' + - 'Django~=3.2.0' + - 'Django~=4.0.0' + - 'Django~=4.1.0' + experimental: [false] +# include: +# - python: '3.9' +# django: 'https://github.com/django/django/archive/refs/heads/main.zip#egg=Django' +# experimental: true +# # NOTE this job will appear to pass even when it fails because of +# # `continue-on-error: true`. Github Actions apparently does not +# # have this feature, similar to Travis' allow-failure, yet. +# # https://github.com/actions/toolkit/issues/399 + exclude: + - python: '3.7' + django: 'Django~=4.0.0' + - python: '3.7' + django: 'Django~=4.1.0' + services: + postgres: + image: postgres:latest + env: + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Setup + run: | + python --version + pip install --upgrade pip wheel + pip install -r requirements/requirements.txt + pip install -r requirements/requirements-testing.txt + pip install "${{ matrix.django }}" + pip freeze + - name: Run tests + env: + DB_SETTINGS: >- + { + "ENGINE":"django.db.backends.postgresql_psycopg2", + "NAME":"entity_event", + "USER":"postgres", + "PASSWORD":"postgres", + "HOST":"localhost", + "PORT":"5432" + } + run: | + coverage run manage.py test entity_event + coverage report --fail-under=100 + continue-on-error: ${{ matrix.experimental }} + - name: Check style + run: flake8 entity_event diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index db541c2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -dist: xenial -language: python -sudo: false - -python: - - "3.6" - - "3.7" - -env: - matrix: - - DJANGO=2.2 - - DJANGO=3.0 - - DJANGO=3.1 - - DJANGO=master - -addons: - postgresql: '9.6' - -matrix: - include: - - { python: "3.6", env: TOXENV=flake8 } - - allow_failures: - - env: DJANGO=master - -install: - - pip install tox-travis - -before_script: - - psql -c 'CREATE DATABASE entity_event;' -U postgres - -script: - - tox - -after_success: - coveralls - -notifications: - email: false diff --git a/docs/release_notes.rst b/docs/release_notes.rst index d4ffd16..0a2192f 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -1,6 +1,12 @@ Release Notes ============= +v3.0.0 +------ +* drop python 3.6 +* support python 3.8, 3.9 +* django 3.2, 4.0, 4.1 + v2.2.1 ------ * Fix bad queryset check which would cause it to evaluate. Add explicit None check. diff --git a/entity_event/tests/context_loader_tests.py b/entity_event/tests/context_loader_tests.py index 7216f91..aedea8a 100644 --- a/entity_event/tests/context_loader_tests.py +++ b/entity_event/tests/context_loader_tests.py @@ -1,3 +1,4 @@ +from django import VERSION from django.test import TestCase from django.test.utils import override_settings from django_dynamic_fixture import N, G @@ -766,7 +767,15 @@ def test_optimal_queries(self): e3 = G(models.Event, context={'key2': test_fk_m1.id, 'key': test_m1.id}, source=s2) e4 = G(models.Event, context={'key2': test_fk_m2.id}, source=s2) - with self.assertNumQueries(5): + # It appears that django >= 3.2 only needs 4 queries because it ignores an "Id in (NULL)" query for the source + # group + # SELECT "entity_event_sourcegroup".* FROM "entity_event_sourcegroup" + # WHERE "entity_event_sourcegroup"."id" IN (NULL) + num_queries = 5 + if (VERSION[0] == 3 and VERSION[1] >= 2) or VERSION[0] >= 4: # pragma: no cover + num_queries = 4 + + with self.assertNumQueries(num_queries): context_loader.load_contexts_and_renderers([e1, e2, e3, e4], [medium1, medium2]) self.assertEquals(e1.context['key'].fk, fk1) self.assertEquals(e2.context['key'][0].fk, fk1) diff --git a/entity_event/version.py b/entity_event/version.py index 36a511e..4eb28e3 100644 --- a/entity_event/version.py +++ b/entity_event/version.py @@ -1 +1 @@ -__version__ = '2.2.1' +__version__ = '3.0.0' diff --git a/requirements/requirements-testing.txt b/requirements/requirements-testing.txt index 1dd1fa8..073bc4f 100644 --- a/requirements/requirements-testing.txt +++ b/requirements/requirements-testing.txt @@ -1,7 +1,7 @@ -coverage==4.5.1 +coverage django-dynamic-fixture -django-nose==1.4.5 -flake8==3.5.0 -freezegun==0.3.12 -mock==2.0.0 -psycopg2>=2.7.7 +django-nose +flake8 +freezegun +mock +psycopg2 diff --git a/settings.py b/settings.py index 14f1664..2e28e4d 100644 --- a/settings.py +++ b/settings.py @@ -1,4 +1,5 @@ import os +import json from django.conf import settings @@ -12,28 +13,30 @@ def configure_settings(): test_db = os.environ.get('DB', None) if test_db is None: db_config = { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'ambition', - 'USER': 'ambition', - 'PASSWORD': 'ambition', - 'HOST': 'db' + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'entity', + 'USER': 'postgres', + 'PASSWORD': '', + 'HOST': 'db', } elif test_db == 'postgres': db_config = { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'entity', 'USER': 'postgres', - 'NAME': 'entity_event', - } - elif test_db == 'sqlite': - db_config = { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'entity_event', + 'PASSWORD': '', + 'HOST': 'db', } else: raise RuntimeError('Unsupported test DB {0}'.format(test_db)) + # Check env for db override (used for github actions) + if os.environ.get('DB_SETTINGS'): + db_config = json.loads(os.environ.get('DB_SETTINGS')) + settings.configure( TEST_RUNNER='django_nose.NoseTestSuiteRunner', + SECRET_KEY='*', NOSE_ARGS=['--nocapture', '--nologcapture', '--verbosity=1'], MIDDLEWARE_CLASSES=(), DATABASES={ diff --git a/setup.py b/setup.py index 7b4dedb..2428484 100755 --- a/setup.py +++ b/setup.py @@ -38,9 +38,9 @@ def get_lines(file_path): packages=find_packages(), classifiers=[ 'Programming Language :: Python', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', @@ -48,6 +48,9 @@ def get_lines(file_path): 'Framework :: Django :: 2.2', 'Framework :: Django :: 3.0', 'Framework :: Django :: 3.1', + 'Framework :: Django :: 3.2', + 'Framework :: Django :: 4.0', + 'Framework :: Django :: 4.1', ], license='MIT', install_requires=install_requires, diff --git a/tox.ini b/tox.ini deleted file mode 100644 index f09dd18..0000000 --- a/tox.ini +++ /dev/null @@ -1,31 +0,0 @@ -[tox] -envlist = - flake8 - py{36,37}-django22 - py{36,37}-django30 - py{36,37}-django31 - py{36,37}-djangomaster - -[testenv] -setenv = - DB = postgres -deps = - django22: Django>=2.2,<3.0 - django30: Django>=3.0,<3.1 - django31: Django>=3.1,<3.2 - djangomaster: https://github.com/django/django/archive/master.tar.gz - -rrequirements/requirements-testing.txt -commands = - coverage run setup.py test - coverage report --fail-under=100 - -[testenv:flake8] -deps = flake8 -commands = flake8 entity_event - -[travis:env] -DJANGO = - 2.2: django22 - 3.0: django30 - 3.1: django31 - master: djangomaster