Replace SimplePatcher with builtin unittest.mock module

The class more or less duplicates the features of the mock module. Can
avoid the duplication by using the stdlib.
This commit is contained in:
Jon Dufresne 2020-02-17 10:01:04 -08:00
parent 53ece804c7
commit 1a3ebafdd2

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")