Merge pull request #4428 from jdufresne/use-mock

Replace SimplePatcher with builtin unittest.mock module
This commit is contained in:
Hugo van Kemenade 2020-02-18 16:08:28 +02:00 committed by GitHub
commit 2d4b4576aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,9 +3,9 @@ import distutils.version
import os import os
import re import re
import shutil import shutil
import sys
import unittest import unittest
from io import BytesIO from io import BytesIO
from unittest import mock
from PIL import Image, ImageDraw, ImageFont, features from PIL import Image, ImageDraw, ImageFont, features
@ -27,32 +27,6 @@ HAS_FREETYPE = features.check("freetype2")
HAS_RAQM = features.check("raqm") HAS_RAQM = features.check("raqm")
class SimplePatcher:
def __init__(self, parent_obj, attr_name, value):
self._parent_obj = parent_obj
self._attr_name = attr_name
self._saved = None
self._is_saved = False
self._value = value
def __enter__(self):
# Patch the attr on the object
if hasattr(self._parent_obj, self._attr_name):
self._saved = getattr(self._parent_obj, self._attr_name)
setattr(self._parent_obj, self._attr_name, self._value)
self._is_saved = True
else:
setattr(self._parent_obj, self._attr_name, self._value)
self._is_saved = False
def __exit__(self, type, value, traceback):
# Restore the original value
if self._is_saved:
setattr(self._parent_obj, self._attr_name, self._saved)
else:
delattr(self._parent_obj, self._attr_name)
@unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available")
class TestImageFont(PillowTestCase): class TestImageFont(PillowTestCase):
LAYOUT_ENGINE = ImageFont.LAYOUT_BASIC LAYOUT_ENGINE = ImageFont.LAYOUT_BASIC
@ -491,7 +465,7 @@ class TestImageFont(PillowTestCase):
def _test_fake_loading_font(self, path_to_fake, fontname): def _test_fake_loading_font(self, path_to_fake, fontname):
# Make a copy of FreeTypeFont so we can patch the original # Make a copy of FreeTypeFont so we can patch the original
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont) free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
with SimplePatcher(ImageFont, "_FreeTypeFont", free_type_font): with mock.patch.object(ImageFont, "_FreeTypeFont", free_type_font, create=True):
def loadable_font(filepath, size, index, encoding, *args, **kwargs): def loadable_font(filepath, size, index, encoding, *args, **kwargs):
if filepath == path_to_fake: if filepath == path_to_fake:
@ -502,7 +476,7 @@ class TestImageFont(PillowTestCase):
filepath, size, index, encoding, *args, **kwargs filepath, size, index, encoding, *args, **kwargs
) )
with SimplePatcher(ImageFont, "FreeTypeFont", loadable_font): with mock.patch.object(ImageFont, "FreeTypeFont", loadable_font):
font = ImageFont.truetype(fontname) font = ImageFont.truetype(fontname)
# Make sure it's loaded # Make sure it's loaded
name = font.getname() name = font.getname()
@ -513,10 +487,9 @@ class TestImageFont(PillowTestCase):
# A lot of mocking here - this is more for hitting code and # A lot of mocking here - this is more for hitting code and
# catching syntax like errors # catching syntax like errors
font_directory = "/usr/local/share/fonts" font_directory = "/usr/local/share/fonts"
with SimplePatcher(sys, "platform", "linux"): with mock.patch("sys.platform", "linux"):
patched_env = copy.deepcopy(os.environ) patched_env = {"XDG_DATA_DIRS": "/usr/share/:/usr/local/share/"}
patched_env["XDG_DATA_DIRS"] = "/usr/share/:/usr/local/share/" with mock.patch.dict(os.environ, patched_env):
with SimplePatcher(os, "environ", patched_env):
def fake_walker(path): def fake_walker(path):
if path == font_directory: if path == font_directory:
@ -534,7 +507,7 @@ class TestImageFont(PillowTestCase):
] ]
return [(path, [], ["some_random_font.ttf"])] return [(path, [], ["some_random_font.ttf"])]
with SimplePatcher(os, "walk", fake_walker): with mock.patch("os.walk", fake_walker):
# Test that the font loads both with and without the # Test that the font loads both with and without the
# extension # extension
self._test_fake_loading_font( self._test_fake_loading_font(
@ -559,7 +532,7 @@ class TestImageFont(PillowTestCase):
# Like the linux test, more cover hitting code rather than testing # Like the linux test, more cover hitting code rather than testing
# correctness. # correctness.
font_directory = "/System/Library/Fonts" font_directory = "/System/Library/Fonts"
with SimplePatcher(sys, "platform", "darwin"): with mock.patch("sys.platform", "darwin"):
def fake_walker(path): def fake_walker(path):
if path == font_directory: if path == font_directory:
@ -577,7 +550,7 @@ class TestImageFont(PillowTestCase):
] ]
return [(path, [], ["some_random_font.ttf"])] return [(path, [], ["some_random_font.ttf"])]
with SimplePatcher(os, "walk", fake_walker): with mock.patch("os.walk", fake_walker):
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial.ttf") self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial.ttf")
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial") self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial")
self._test_fake_loading_font(font_directory + "/Single.otf", "Single") self._test_fake_loading_font(font_directory + "/Single.otf", "Single")