diff --git a/Jenkinsfile b/Jenkinsfile index 4cd8729..265f636 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,8 +12,11 @@ pipeline { always { script { utils = new Utils() + utils.publish_coverage('coverage.xml') + utils.publish_coverage_native('index.html') utils.publish_pylint('pylint.out') } + mergeJunitResults() } } } diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..c184c0f --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +DJANGO_SETTINGS_MODULE = tests.project.settings diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..342da17 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,10 @@ +import pytest + + +@pytest.fixture +def nocache(settings): + settings.CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', + } + } diff --git a/tests/project/__init__.py b/tests/project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/project/settings.py b/tests/project/settings.py new file mode 100644 index 0000000..93c3e96 --- /dev/null +++ b/tests/project/settings.py @@ -0,0 +1,36 @@ +import os + +DATABASES = { + 'default': { + 'ENGINE': os.environ.get('DB_ENGINE', 'django.db.backends.postgresql_psycopg2'), + 'NAME': 'gadjo-test-%s' % os.environ.get("BRANCH_NAME", "").replace('/', '-')[:45], + } +} + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [], + 'builtins': [ + 'gadjo.templatetags.gadjo', + ], + }, + }, +] + + +DEBUG = True +USE_TZ = True +INSTALLED_APPS = [ + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sites", +] +STATIC_URL = "/static/" +SITE_ID = 1 +MIDDLEWARE_CLASSES = () +LOGGING = {} +SECRET_KEY = "yay" diff --git a/tests/test_finder.py b/tests/test_finder.py new file mode 100644 index 0000000..53dd7ef --- /dev/null +++ b/tests/test_finder.py @@ -0,0 +1,6 @@ +import gadjo.finders + + +def test_finder(): + finder = gadjo.finders.XStaticFinder() + assert len(finder.find(path='', all=True)) == 4 diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py new file mode 100644 index 0000000..e892d39 --- /dev/null +++ b/tests/test_templatetags.py @@ -0,0 +1,34 @@ +import html +import urllib + +from django.template import Context, Template +from django.test.client import RequestFactory + + +def test_start_timestamp(): + t = Template('{% start_timestamp %}') + assert t.render(Context()) + + +def test_querystring(): + t = Template('{% querystring "name"="Ayers" "age"=20 %}') + ctx = Context({'request': RequestFactory().get('/')}) + assert urllib.parse.parse_qs(urllib.parse.urlparse(html.unescape(t.render(ctx))).query) == { + 'age': ['20'], + 'name': ['Ayers'], + } + ctx = Context({'request': RequestFactory().get('/?age=10')}) + assert urllib.parse.parse_qs(urllib.parse.urlparse(html.unescape(t.render(ctx))).query) == { + 'age': ['20'], + 'name': ['Ayers'], + } + + t = Template('{% querystring "name"="Ayers" without "gender" %}') + ctx = Context({'request': RequestFactory().get('/')}) + assert urllib.parse.parse_qs(urllib.parse.urlparse(html.unescape(t.render(ctx))).query) == { + 'name': ['Ayers'] + } + ctx = Context({'request': RequestFactory().get('/?gender=male')}) + assert urllib.parse.parse_qs(urllib.parse.urlparse(html.unescape(t.render(ctx))).query) == { + 'name': ['Ayers'] + } diff --git a/tests/test_widgets.py b/tests/test_widgets.py new file mode 100644 index 0000000..1befaef --- /dev/null +++ b/tests/test_widgets.py @@ -0,0 +1,28 @@ +from django import forms +from django.template import Context, Template +from django.test.client import RequestFactory +from pyquery import PyQuery + +from gadjo.forms.widgets import MultiSelectWidget + + +def test_multiselect_widget(): + class ExampleForm(forms.Form): + choices = forms.MultipleChoiceField( + label='choices', choices=[('a', 'Aa'), ('b', 'Bb'), ('c', 'Cc')], widget=MultiSelectWidget + ) + + request = RequestFactory().get('/') + t = Template('{{ form|with_template }}') + ctx = Context({'request': request, 'form': ExampleForm()}) + rendered = t.render(ctx) + assert len(PyQuery(rendered).find('select')) == 1 + assert PyQuery(rendered).find('.gadjo-multi-select-widget--button-add') + + request = RequestFactory().get('/?choices=a&choices=b') + t = Template('{{ form|with_template }}') + ctx = Context({'request': request, 'form': ExampleForm(data=request.GET)}) + rendered = t.render(ctx) + assert len(PyQuery(rendered).find('select')) == 2 + assert PyQuery(rendered).find('option[selected]').text() == 'Aa Bb' + assert ctx['form'].cleaned_data == {'choices': ['a', 'b']} diff --git a/tox.ini b/tox.ini index e4d6daa..5ce7e44 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,27 @@ [tox] -envlist = codestyle-pylint +envlist = codestyle-coverage-pylint toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/gadjo/{env:BRANCH_NAME:} [testenv] +usedevelop = + coverage: True + nocoverage: False +setenv = + SETUPTOOLS_USE_DISTUTILS=stdlib + JUNIT=--junitxml=junit-{envname}.xml + coverage: COVERAGE=--cov-report xml --cov-report html --cov=gadjo/ deps = + pytest + pytest-django + WebTest + psycopg2-binary + psycopg2 codestyle: pre-commit + coverage: pytest-cov pylint: pylint pylint: pylint-django pylint: django>=3.2,<3.3 commands = + pytest {posargs: {env:JUNIT:} {env:COVERAGE:} tests/} codestyle: pre-commit run --all-files --show-diff-on-failure pylint: ./pylint.sh gadjo/