Skip to content

Commit

Permalink
Use pytest instead of nose
Browse files Browse the repository at this point in the history
Also:
- Test Against Python 3.10
- Stop testing for Python 3.4
  • Loading branch information
vstoykov committed Feb 17, 2022
1 parent 2a9ad30 commit b2c7d9d
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 64 deletions.
9 changes: 9 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[run]
branch = true
parallel = true

[report]
show_missing = true
skip_empty = true
skip_covered = true
precision = 2
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, "3.10"]

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*.pyc
.DS_Store
.tox
.coverage
.vscode
MANIFEST
build
dist
Expand Down
18 changes: 4 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
import os
from setuptools import setup, find_packages

# Workaround for multiprocessing/nose issue. See http://bugs.python.org/msg170215
try:
import multiprocessing
except ImportError:
pass

read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read()
def read(filepath):
with codecs.open(filepath, 'r', 'utf-8') as f:
return f.read()

# Load package meta from the pkgmeta module without loading the package.
pkgmeta = {}
Expand All @@ -31,13 +28,6 @@
packages=find_packages(exclude=['tests', 'tests.*']),
zip_safe=False,
include_package_data=True,
tests_require=[
'mock>=1.0.1',
'nose>=1.3.6',
'nose-progressive>=1.5.1',
'Pillow',
],
test_suite='nose.collector',
install_requires=[],
classifiers=[
'Development Status :: 5 - Production/Stable',
Expand All @@ -47,12 +37,12 @@
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Topic :: Utilities'
],
)
49 changes: 23 additions & 26 deletions tests/test_processors.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import os
import mock
import pytest

from pilkit.lib import Image, ImageDraw, ImageColor
from pilkit.processors import (Resize, ResizeToFill, ResizeToFit, SmartCrop,
SmartResize, MakeOpaque, ColorOverlay, Convert,
GaussianBlur)
from nose.tools import eq_, assert_true
import os
from pilkit.processors.resize import Thumbnail
from .utils import create_image, compare_images, get_image_file
import mock


def test_smartcrop():
img = SmartCrop(100, 100).process(create_image())
eq_(img.size, (100, 100))
assert img.size == (100, 100)


def test_resizetofill():
img = ResizeToFill(100, 100).process(create_image())
eq_(img.size, (100, 100))
assert img.size == (100, 100)


def test_resizetofit():
Expand All @@ -27,7 +28,7 @@ def test_resizetofit():
img = ResizeToFit(100, 100).process(img)

# Assert that the image has maintained the aspect ratio.
eq_(img.size, (100, 50))
assert img.size == (100, 50)


def test_resize_rounding():
Expand All @@ -37,13 +38,13 @@ def test_resize_rounding():

img = Image.new('RGB', (95, 95))
img = ResizeToFill(28, 28).process(img)
eq_(img.size, (28, 28))
assert img.size == (28, 28)


def test_resizetofit_mat():
img = Image.new('RGB', (200, 100))
img = ResizeToFit(100, 100, mat_color=0x000000).process(img)
eq_(img.size, (100, 100))
assert img.size == (100, 100)


def test_coloroverlay():
Expand All @@ -53,16 +54,16 @@ def test_coloroverlay():
img = Image.new('RGB', (200, 100))
color = ImageColor.getrgb('#cc0000')
img = ColorOverlay(color, overlay_opacity=1.0).process(img)
eq_(img.getpixel((0,0)), (204, 0, 0))
assert img.getpixel((0,0)) == (204, 0, 0)

def test_convert():
img = Image.new('RGBA', (200, 100))

img_RGBa = Convert("RGBa").process(img)
eq_(img_RGBa.mode, "RGBa")
assert img_RGBa.mode == "RGBa"

img_RGBa_RGBA = Convert("RGBA").process(img)
eq_(img_RGBa_RGBA.mode, "RGBA")
assert img_RGBa_RGBA.mode == "RGBA"


def test_resize_antialiasing():
Expand Down Expand Up @@ -92,7 +93,7 @@ def test_resize_antialiasing():
# Count the number of colors
color_count = len(list(filter(None, img.histogram())))

assert_true(color_count > 2)
assert color_count > 2


def test_upscale():
Expand All @@ -105,37 +106,33 @@ def test_upscale():

for P in [Resize, ResizeToFit, ResizeToFill, SmartResize]:
img2 = P(500, 500, upscale=True).process(img)
eq_(img2.size, (500, 500))
assert img2.size == (500, 500)

img2 = P(500, 500, upscale=False).process(img)
eq_(img2.size, (100, 100))
assert img2.size == (100, 100)


def test_should_raise_exception_if_anchor_is_passed_and_crop_is_set_to_false():
try:
with pytest.raises(Exception, match=r"You can't specify an anchor point if crop is False."):
Thumbnail(height=200, width=200, upscale=False, crop=False, anchor='t')
except Exception as e:
eq_(str(e), "You can't specify an anchor point if crop is False.")


def test_should_set_crop_to_true_if_anchor_is_passed_without_crop():
thumb = Thumbnail(height=200, width=200, upscale=False, anchor='t')
assert_true(thumb.crop)
assert thumb.crop


def test_should_raise_exception_when_crop_is_passed_without_height_and_width():
img = Image.new('RGB', (100, 100))
try:
with pytest.raises(Exception, match=r"You must provide both a width and height when cropping."):
Thumbnail(crop=True).process(img)
except Exception as e:
eq_(str(e), 'You must provide both a width and height when cropping.')


@mock.patch('pilkit.processors.resize.SmartResize')
def test_should_call_smartresize_when_crop_not_passed(my_mock):
img = Image.new('RGB', (100, 100))
Thumbnail(height=200, width=200, upscale=False).process(img)
assert_true(my_mock.called)
assert my_mock.called


@mock.patch('pilkit.processors.resize.SmartResize')
Expand All @@ -156,27 +153,27 @@ def test_should_repass_upscale_option_false(my_mock):
def test_should_call_resizetofill_when_crop_and_ancho_is_passed(my_mock):
img = Image.new('RGB', (100, 100))
Thumbnail(height=200, width=200, anchor='fake').process(img)
assert_true(my_mock.called)
assert my_mock.called

@mock.patch('pilkit.processors.resize.ResizeToFit')
def test_should_call_resizetofit_when_crop_is_not_passed(my_mock):
img = Image.new('RGB', (100, 100))
Thumbnail(height=200, width=200, crop=False).process(img)
assert_true(my_mock.called)
assert my_mock.called

def test_GaussianBlur_radius_3():
img = GaussianBlur(radius = 3).process(create_image())
img = img.crop((112,112,144,144))

expected_img = Image.open(get_image_file("GaussianBlur_radius_3.png"))
assert_true(compare_images(img, expected_img))
assert compare_images(img, expected_img)

def test_GaussianBlur_radius_7():
img = GaussianBlur(radius=7).process(create_image())
img = img.crop((112, 112, 144, 144))

expected_img = Image.open(get_image_file("GaussianBlur_radius_7.png"))
assert_true(compare_images(img, expected_img))
assert compare_images(img, expected_img)

def test_make_gifs_opaque():
dir = os.path.dirname(__file__)
Expand Down
42 changes: 22 additions & 20 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import os
from io import UnsupportedOperation
import io
import pytest
from mock import Mock, patch
from tempfile import NamedTemporaryFile

from pilkit.exceptions import UnknownFormat, UnknownExtension
from pilkit.lib import Image
from pilkit.utils import (extension_to_format, format_to_extension, FileWrapper,
save_image, prepare_image, quiet)
from mock import Mock, patch
from nose.tools import eq_, raises, ok_
from tempfile import NamedTemporaryFile

from .utils import create_image


def test_extension_to_format():
eq_(extension_to_format('.jpeg'), 'JPEG')
eq_(extension_to_format('.rgba'), 'SGI')
assert extension_to_format('.jpeg') == 'JPEG'
assert extension_to_format('.rgba') == 'SGI'


def test_format_to_extension_no_init():
eq_(format_to_extension('PNG'), '.png')
eq_(format_to_extension('ICO'), '.ico')
assert format_to_extension('PNG') == '.png'
assert format_to_extension('ICO') == '.ico'


@raises(UnknownFormat)
def test_unknown_format():
format_to_extension('TXT')
with pytest.raises(UnknownFormat):
format_to_extension('TXT')


@raises(UnknownExtension)
def test_unknown_extension():
extension_to_format('.txt')
with pytest.raises(UnknownExtension):
extension_to_format('.txt')


def test_default_extension():
Expand All @@ -40,17 +42,17 @@ def test_default_extension():
extensions we'd prefer, and this tests to make sure it's working.
"""
eq_(format_to_extension('JPEG'), '.jpg')
assert format_to_extension('JPEG') == '.jpg'


@raises(AttributeError)
def test_filewrapper():

class K(object):
def fileno(self):
raise UnsupportedOperation
raise io.UnsupportedOperation

FileWrapper(K()).fileno()
with pytest.raises(AttributeError):
FileWrapper(K()).fileno()


def test_save_with_filename():
Expand All @@ -60,9 +62,8 @@ def test_save_with_filename():
"""
im = create_image()
outfile = NamedTemporaryFile()
save_image(im, outfile.name, 'JPEG')
outfile.close()
with NamedTemporaryFile() as outfile:
save_image(im, outfile.name, 'JPEG')


def test_format_normalization():
Expand All @@ -71,7 +72,8 @@ def test_format_normalization():
See https://github.com/matthewwithanm/django-imagekit/issues/262
"""
im = Image.new('RGBA', (100, 100))
ok_('transparency' in prepare_image(im, 'gIF')[1])
assert 'transparency' in prepare_image(im, 'gIF')[1]


def test_quiet():
"""
Expand Down
20 changes: 17 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
[tox]
envlist =
py{39,38,37,36,35,34,27}
py{310,39,38,37,36,35,27},
coverage-report

[testenv]
commands = python setup.py test
setenv = COVERAGE_FILE=.coverage.{envname}
commands = python -m pytest --cov --cov-report term-missing:skip-covered
deps =
py34: Pillow<6
pytest
pytest-cov
mock>=1.0.1
Pillow


[testenv:coverage-report]
deps = coverage
skip_install = true
setenv = COVERAGE_FILE=.coverage
commands =
coverage combine
coverage report

0 comments on commit b2c7d9d

Please sign in to comment.