Skip to content

Commit

Permalink
add tests, github actions (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
vigo committed May 23, 2024
1 parent 1a6c98b commit 2df791a
Show file tree
Hide file tree
Showing 21 changed files with 450 additions and 1 deletion.
26 changes: 26 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Ruff Linter

on:
pull_request:
push:
branches:
- main
tags-ignore:
- '**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install ruff
- name: Run Ruff
run: ruff check --output-format=github .
37 changes: 37 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Tests

on:
pull_request:
push:
branches:
- main
tags-ignore:
- '**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install codecov
- name: Run Tests with coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
pytest -s --cov=src/dalf --cov-report=xml tests/testproject
codecov -f coverage.xml
- name: Upload coverage to Codecov
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
flags: unittests
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
[![Ruff](https://img.shields.io/endpoint?style=for-the-badge&url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![PyPI version](https://img.shields.io/pypi/v/dalf.svg?style=for-the-badge)](https://pypi.org/project/dalf/)
![PyPI - Downloads](https://img.shields.io/pypi/dm/dalf?style=for-the-badge)
[![Codecov](https://codecov.io/gh/vigo/django-admin-list-filter/graph/badge.svg?token=6JRNSB6WN1)](https://codecov.io/gh/vigo/django-admin-list-filter)


# Django Admin List Filter

Expand Down Expand Up @@ -216,6 +218,7 @@ rake -T
rake build # Build package
rake bump[revision] # Bump version: major,minor,patch
rake clean # Remove/Delete build..
rake test # Run tests
rake upload:main # Upload package to main distro (release)
rake upload:test # Upload package to test distro
```
Expand All @@ -224,6 +227,10 @@ rake upload:test # Upload package to test distro

## Change Log

**2024-05-23**

- Add tests

**2024-05-20**

- Initial release.
Expand Down
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ task :bump, [:revision] do |t, args|
abort "Please provide valid revision: #{AVAILABLE_REVISIONS.join(',')}" unless AVAILABLE_REVISIONS.include?(args.revision)
system "bumpversion #{args.revision}"
end

desc "Run tests"
task :test do
system %{
pytest -s --cov=src/dalf --cov-report=xml tests/testproject
}
end
8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ version = "0.1.0"
authors = [
{ name="Uğur Özyılmazel", email="[email protected]" },
]
description = "Django admin list filter with goodies"
description = "Dead simple autocompletion for Django admin list_filter with goodies."
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.11"
classifiers = [
"Programming Language :: Python :: 3",
Expand All @@ -14,6 +15,11 @@ classifiers = [
"Framework :: Django :: 5.0",
"Development Status :: 3 - Alpha",
]
keywords = ["django", "django admin", "list filter"]

[project.optional-dependencies]
build = ["build", "twine"]
dev = ["Django", "pytest", "pytest-django", "pytest-factoryboy", "pytest-cov"]

[project.urls]
Homepage = "https://github.com/vigo/django-admin-list-filter"
Expand Down
5 changes: 5 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Django==5.0.6
pytest==8.2.1
pytest-cov==5.0.0
pytest-django==4.8.0
pytest-factoryboy==2.7.0
23 changes: 23 additions & 0 deletions tests/testproject/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# ruff: noqa: TRY003,EM101

import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testproject.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
'available on your PYTHONPATH environment variable? Did you '
'forget to activate a virtual environment?'
) from exc
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()
5 changes: 5 additions & 0 deletions tests/testproject/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[pytest]
DJANGO_SETTINGS_MODULE = testproject.settings
python_files = tests.py test_*.py *_tests.py
pythonpath = ../../src
addopts = -p no:warnings --strict-markers --no-migrations --reuse-db --capture=no
Empty file.
33 changes: 33 additions & 0 deletions tests/testproject/testapp/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from dalf.admin import (
DALFChoicesField,
DALFModelAdmin,
DALFRelatedField,
DALFRelatedFieldAjax,
DALFRelatedOnlyField,
)
from django.contrib import admin

from .models import Category, Post, Tag


@admin.register(Post)
class PostAdmin(DALFModelAdmin):
list_display = ('title',)
list_filter = (
('author', DALFRelatedField),
('audience', DALFChoicesField),
('category', DALFRelatedFieldAjax),
('tags', DALFRelatedOnlyField),
)


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
search_fields = ('name',)
ordering = ('name',)


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
search_fields = ('name',)
ordering = ('name',)
6 changes: 6 additions & 0 deletions tests/testproject/testapp/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class TestappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'testapp'
12 changes: 12 additions & 0 deletions tests/testproject/testapp/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest
from pytest_factoryboy import register

from .factories import PostFactory, TagFactory

register(TagFactory)
register(PostFactory)


@pytest.fixture()
def posts():
return PostFactory.create_batch(10)
77 changes: 77 additions & 0 deletions tests/testproject/testapp/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import factory
from django.contrib.auth import get_user_model
from factory import fuzzy

from .models import AudienceChoices, Category, Post, Tag

FAKE_USERNAMES = [
'vigo',
'turbo',
'move',
]

FAKE_CATEGORIES = [
'Python',
'Ruby',
'Go',
'Bash',
'AppleScript',
'C',
'Perl',
]

FAKE_TAGS = [
'django',
'django rest',
'linux',
'macos',
'stdlib',
]


class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = get_user_model()
django_get_or_create = ('username',)

username = fuzzy.FuzzyChoice(FAKE_USERNAMES)
email = factory.Faker('email')
password = factory.PostGenerationMethodCall('set_password', 'defaultpassword')


class CategoryFactory(factory.django.DjangoModelFactory):
class Meta:
model = Category
django_get_or_create = ('name',)

name = factory.Iterator(FAKE_CATEGORIES)


class TagFactory(factory.django.DjangoModelFactory):
class Meta:
model = Tag
django_get_or_create = ('name',)

name = fuzzy.FuzzyChoice(FAKE_TAGS)


class PostFactory(factory.django.DjangoModelFactory):
class Meta:
model = Post
django_get_or_create = ('title',)

author = factory.SubFactory(UserFactory)
category = factory.SubFactory(CategoryFactory)
title = factory.Sequence(lambda n: f'Book about {FAKE_CATEGORIES[n % len(FAKE_CATEGORIES)]} - {n}')
audience = fuzzy.FuzzyChoice(AudienceChoices.choices, getter=lambda c: c[0])

@factory.post_generation
def tags(self, create, extracted, **kwargs): # noqa: ARG002
if not create:
return

if extracted:
self.tags.add(*extracted)
else:
tags = TagFactory.create_batch(len(FAKE_TAGS))
self.tags.add(*tags)
Empty file.
46 changes: 46 additions & 0 deletions tests/testproject/testapp/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from django.conf import settings
from django.db import models


class Category(models.Model):
name = models.CharField(max_length=255)

def __str__(self):
return self.name


class Tag(models.Model):
name = models.CharField(max_length=255)

def __str__(self):
return self.name


class AudienceChoices(models.TextChoices):
BEGINNER = 'beginner', 'Beginer'
INTERMEDIATE = 'intermediate', 'Intermediate'
PRO = 'pro', 'Pro'


class Post(models.Model):
author = models.ForeignKey(
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='posts',
)
category = models.ForeignKey(
to='Category',
on_delete=models.CASCADE,
related_name='posts',
)
tags = models.ManyToManyField(to='Tag', blank=True)
audience = models.CharField(
max_length=100,
choices=AudienceChoices.choices,
default=AudienceChoices.BEGINNER,
)

title = models.CharField(max_length=255)

def __str__(self):
return self.title
Loading

0 comments on commit 2df791a

Please sign in to comment.