Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to pytest, replace travis with github actions #74

Merged
merged 4 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[report]
omit =
cropduster/*migrations/*

19 changes: 19 additions & 0 deletions .github/workflows/apt-get-update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

set -eo pipefail

aptget_update()
{
if [ ! -z $1 ]; then
echo ""
echo "Retrying apt-get update..."
echo ""
fi
output=`sudo apt-get update 2>&1`
echo "$output"
if [[ $output == *[WE]:\ * ]]; then
return 1
fi
}

aptget_update || aptget_update retry || aptget_update retry
114 changes: 114 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Test

on: [push, pull_request]

jobs:
build:
strategy:
fail-fast: false
matrix:
python-version: ["2.7", "3.6", "3.7"]
django-version: ["1.11", "2.2"]
grappelli: ["0", "1"]
s3: ["0", "1"]
exclude:
- python-version: "2.7"
django-version: "2.2"
- grappelli: "1"
s3: "1"
- python-version: "3.7"
django-version: "1.11"
- python-version: "3.8"
django-version: "1.11"
- python-version: "3.6"
s3: "1"
include:
- python-version: "2.7"
python-bin: python2
- python-version: "3.6"
python-bin: python3
- python-version: "3.7"
python-bin: python3
- s3: "1"
name-suffix: " with S3 storage"
- grappelli: "1"
name-suffix: " with grappelli"
- s3: "0"
grappelli: "0"
name-suffix: ""

runs-on: ubuntu-latest
name: Django ${{ matrix.django-version }}${{ matrix.name-suffix }} (Python ${{ matrix.python-version }})

env:
DJANGO: ${{ matrix.django-version }}
GRAPPELLI: ${{ matrix.grappelli }}
S3: ${{ matrix.s3 }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Setup chromedriver
uses: nanasess/[email protected]

- name: Install system dependencies
run: |
sudo .github/workflows/apt-get-update.sh
sudo apt-get install -y exempi gifsicle

- name: Install tox
run: |
${{ matrix.python-bin }} -m pip install tox tox-gh-actions

- name: Run tests
run: |
tox -- -v --selenosis-driver=chrome-headless || \
tox -- -v --selenosis-driver=chrome-headless || \
tox -- -v --selenosis-driver=chrome-headless

- name: Upload junit xml
if: always()
uses: actions/upload-artifact@v2
with:
name: junit-reports
path: reports/*.xml

- name: Combine coverage
run: tox -e coverage-report

- name: Upload coverage
run: tox -e codecov
env:
CODECOV_NAME: ${{ github.workflow }}

report:
if: always()
needs: build
runs-on: ubuntu-latest
name: "Report Test Results"
steps:
- uses: actions/download-artifact@v2
with:
name: junit-reports

- name: Publish Unit Test Results
uses: EnricoMi/[email protected]
if: always()
with:
files: ./*.xml
report_individual_runs: true

success:
needs: build
runs-on: ubuntu-latest
name: Test Successful
steps:
- name: Success
run: echo Test Successful
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ build
ghostdriver.log
test/media
dist/
.coverage
/reports/
41 changes: 0 additions & 41 deletions .travis.yml

This file was deleted.

1 change: 1 addition & 0 deletions cropduster/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class CropDusterWidget(GenericForeignFileWidget):
class Media:
css = {'all': ('cropduster/css/cropduster.css',)}
js = (
'admin/js/jquery.init.js',
'cropduster/js/jsrender.js',
'cropduster/js/cropduster.js',
)
Expand Down
2 changes: 1 addition & 1 deletion cropduster/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def get_jpeg_quality(width, height):
"CROPDUSTER_JPEG_QUALITY setting must be either a callable "
"or a numeric value, got type %s" % (type(CROPDUSTER_JPEG_QUALITY).__name__))

JPEG_SAVE_ICC_SUPPORTED = (LooseVersion(getattr(PIL, 'PILLOW_VERSION', '0'))
JPEG_SAVE_ICC_SUPPORTED = (LooseVersion(getattr(PIL, '__version__', '0'))
>= LooseVersion('2.2.1'))

CROPDUSTER_GIFSICLE_PATH = getattr(settings, 'CROPDUSTER_GIFSICLE_PATH', None)
Expand Down
8 changes: 0 additions & 8 deletions cropduster/tests/admin.py

This file was deleted.

Empty file.
2 changes: 1 addition & 1 deletion cropduster/utils/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def smart_resize(im, final_w, final_h):

# Pillow 2.7.0 greatly improved the bicubic resize algorithm, which makes
# our multiple-step resizing unnecessary
pillow_version = getattr(PIL, 'PILLOW_VERSION', None)
pillow_version = getattr(PIL, '__version__', None)
if pillow_version and LooseVersion(pillow_version) >= LooseVersion('2.7.0'):
return im.resize((final_w, final_h), PIL.Image.BICUBIC)

Expand Down
6 changes: 6 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[pytest]
DJANGO_SETTINGS_MODULE = tests.settings
addopts = --tb=short --create-db --cov=cropduster
django_find_project = false
python_files = tests.py test_*.py *_tests.py
testpaths = tests
20 changes: 0 additions & 20 deletions runtests.py

This file was deleted.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
author_email='[email protected]',
url='https://github.com/theatlantic/django-cropduster',
description='Django image uploader and cropping tool',
packages=find_packages(),
packages=find_packages(exclude=["tests"]),
zip_safe=False,
long_description=open('README.rst').read(),
license='BSD',
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions tests/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.contrib import admin
from .models import Author, Article, OptionalSizes, OrphanedThumbs


admin.site.register(Author)
admin.site.register(Article)
admin.site.register(OptionalSizes)
admin.site.register(OrphanedThumbs)
13 changes: 13 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import warnings

import pytest
from django.test import TestCase


TestCase.pytestmark = pytest.mark.django_db(transaction=True, reset_sequences=True)


@pytest.fixture(autouse=True)
def suppress_warnings():
warnings.simplefilter("error", Warning)
warnings.filterwarnings('ignore', message='.*?ckeditor')
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
29 changes: 19 additions & 10 deletions cropduster/tests/helpers.py → tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,29 @@ def assertImageColorEqual(self, element, image):
scroll_top = -1 * self.selenium.execute_script(
'return document.body.getBoundingClientRect().top')
tmp_file = tempfile.NamedTemporaryFile(suffix='.png')
if not self.selenium.save_screenshot(tmp_file.name):
raise Exception("Failed to save screenshot")
pixel_density = self.selenium.execute_script('return window.devicePixelRatio') or 1
im1 = PIL.Image.open(tmp_file.name).convert('RGB')
x1 = int(round(element.location['x'] + (element.size['width'] // 2.0)))
y1 = int(round(element.location['y'] - scroll_top + (element.size['height'] // 2.0)))
rgb1 = im1.getpixel((x1 * pixel_density, y1 * pixel_density))
im2 = PIL.Image.open(os.path.join(os.path.dirname(__file__), 'data', image)).convert('RGB')
w, h = im2.size

image_path = os.path.join(os.path.dirname(__file__), 'data', image)
ref_im = PIL.Image.open(image_path).convert('RGB')
w, h = ref_im.size
x2, y2 = int(round(w // 2.0)), int(round(h // 2.0))
rgb2 = im2.getpixel((x2, y2))
if rgb1 != rgb2:
msg = "Colors differ: %s != %s" % (repr_rgb(rgb1), repr_rgb(rgb2))
self.fail(msg)
ref_rgb = ref_im.getpixel((x2, y2))
ref_im.close()

def get_screenshot_rgb():
if not self.selenium.save_screenshot(tmp_file.name):
raise Exception("Failed to save screenshot")
im = PIL.Image.open(tmp_file.name).convert('RGB')
rgb = im.getpixel((x1 * pixel_density, y1 * pixel_density))
im.close()
return rgb

self.wait_until(
lambda d: get_screenshot_rgb() == ref_rgb,
message=(
"Colors differ: %s != %s" % (repr_rgb(ref_rgb), repr_rgb(get_screenshot_rgb()))))

def create_unique_image(self, image):
image_uuid = uuid.uuid4().hex
Expand Down
Loading