imagetk.py testing imp draft

This commit is contained in:
Deekshu Kare 2024-06-22 14:23:01 +02:00
parent f206a1c617
commit 293ea08ece
6 changed files with 46 additions and 62 deletions

View File

@ -698,28 +698,3 @@ def test_deprecation() -> None:
assert ImageCms.VERSION == "1.0.0 pil" assert ImageCms.VERSION == "1.0.0 pil"
with pytest.warns(DeprecationWarning): with pytest.warns(DeprecationWarning):
assert isinstance(ImageCms.FLAGS, dict) assert isinstance(ImageCms.FLAGS, dict)
class TestGetOpenProfile:
def test_get_open_profile_with_string_path(self, tmp_path: Path) -> None:
# Create a dummy profile file
dummy_profile_path = tmp_path / "dummy.icc"
dummy_profile_path.write_bytes(b"Dummy ICC content")
# Test with a string path
profile = ImageCms.getOpenProfile(str(dummy_profile_path))
assert isinstance(profile, ImageCms.ImageCmsProfile)
def test_get_open_profile_with_file_object(self, tmp_path: Path) -> None:
# Create a dummy profile file content
dummy_profile_content = b"Dummy ICC content"
dummy_profile_file = BytesIO(dummy_profile_content)
# Test with a file-like object
profile = ImageCms.getOpenProfile(dummy_profile_file)
assert isinstance(profile, ImageCms.ImageCmsProfile)
def test_get_open_profile_with_invalid_input(self) -> None:
# Test with invalid input
with pytest.raises(TypeError):
ImageCms.getOpenProfile(123) # Assuming passing an integer is invalid

View File

@ -215,13 +215,13 @@ class MockPyDecoder(ImageFile.PyDecoder):
class MockPyEncoder(ImageFile.PyEncoder): class MockPyEncoder(ImageFile.PyEncoder):
last = None # Add this line last = None
def __init__(self, mode: str, *args: Any) -> None: def __init__(self, mode: str, *args: Any) -> None:
super().__init__(mode, *args) super().__init__(mode, *args)
self._pushes_fd = False self._pushes_fd = False
self.cleanup_called = False self.cleanup_called = False
MockPyEncoder.last = self # Update this line MockPyEncoder.last = self
def encode(self, buffer): def encode(self, buffer):
# Simulate encoding # Simulate encoding

View File

@ -1,25 +1,23 @@
from __future__ import annotations from __future__ import annotations
import gc
import pytest import pytest
import tkinter as tk
from unittest import mock
from PIL import Image from PIL import Image
from PIL import ImageTk
from .helper import assert_image_equal, hopper from .helper import assert_image_equal, hopper
TK_MODES = ("1", "L", "P", "RGB", "RGBA")
try: try:
import tkinter as tk
from PIL import ImageTk
dir(ImageTk) dir(ImageTk)
HAS_TK = True HAS_TK = True
except (OSError, ImportError): except (OSError, ImportError):
# Skipped via pytestmark
HAS_TK = False HAS_TK = False
TK_MODES = ("1", "L", "P", "RGB", "RGBA")
pytestmark = pytest.mark.skipif(not HAS_TK, reason="Tk not installed") pytestmark = pytest.mark.skipif(not HAS_TK, reason="Tk not installed")
@ -27,7 +25,6 @@ def setup_module() -> None:
try: try:
# setup tk # setup tk
tk.Frame() tk.Frame()
# root = tk.Tk()
except RuntimeError as v: except RuntimeError as v:
pytest.skip(f"RuntimeError: {v}") pytest.skip(f"RuntimeError: {v}")
except tk.TclError as v: except tk.TclError as v:
@ -102,3 +99,28 @@ def test_bitmapimage() -> None:
# reloaded = ImageTk.getimage(im_tk) # reloaded = ImageTk.getimage(im_tk)
# assert_image_equal(reloaded, im) # assert_image_equal(reloaded, im)
def test_bitmapimage_del() -> None:
# Set up an image
im = Image.new("1", (10, 10))
# Mock the tkinter PhotoImage to track calls
with mock.patch.object(tk, 'BitmapImage', wraps=tk.BitmapImage) as mock_bitmapimage:
# Create an instance of BitmapImage
bitmap_image = ImageTk.BitmapImage(im)
# Ensure the BitmapImage was created
assert mock_bitmapimage.call_count == 1
# Get the internal Tkinter image object
tk_image = bitmap_image._BitmapImage__photo
# Mock the tk.call method to track the 'image delete' call
with mock.patch.object(tk_image.tk, 'call', wraps=tk_image.tk.call) as mock_tk_call:
# Delete the instance and force garbage collection
del bitmap_image
gc.collect()
# Check that the 'image delete' command was called
mock_tk_call.assert_any_call("image", "delete", tk_image.name)

View File

@ -4,8 +4,7 @@ import sys
from PIL import Image from PIL import Image
from PIL import PdfParser from PIL import PdfParser
from PIL import ImageCms from PIL import ImageTk
from PIL import McIdasImagePlugin
from PIL import ImageFile from PIL import ImageFile
pytest_plugins = ["Tests.helper"] pytest_plugins = ["Tests.helper"]
@ -15,9 +14,8 @@ def calculate_coverage(test_name):
all_branches = { all_branches = {
"branches1": Image.branches, "branches1": Image.branches,
"branches2": PdfParser.XrefTable.branches, "branches2": PdfParser.XrefTable.branches,
"branches3": ImageCms.PyCMSError.branches, "branches3": ImageTk.BitmapImage.branches,
"branches4": McIdasImagePlugin.McIdasImageFile.branches, "branches4": ImageFile.PyEncoder.branches,
"branches5": ImageFile.PyEncoder.branches,
# Add more # Add more
} }

View File

@ -31,6 +31,10 @@ from io import BytesIO
from . import Image from . import Image
branches = {
"1": False,
"2": False,
}
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Check for Tkinter interface hooks # Check for Tkinter interface hooks
@ -188,6 +192,10 @@ class PhotoImage:
class BitmapImage: class BitmapImage:
branches = {
"1": False,
"2": False,
}
""" """
A Tkinter-compatible bitmap image. This can be used everywhere Tkinter A Tkinter-compatible bitmap image. This can be used everywhere Tkinter
expects an image object. expects an image object.
@ -223,8 +231,10 @@ class BitmapImage:
name = self.__photo.name name = self.__photo.name
self.__photo.name = None self.__photo.name = None
try: try:
BitmapImage.branches["1"] = True
self.__photo.tk.call("image", "delete", name) self.__photo.tk.call("image", "delete", name)
except Exception: except Exception:
BitmapImage
pass # ignore internal errors pass # ignore internal errors
def width(self) -> int: def width(self) -> int:

View File

@ -21,14 +21,6 @@ import struct
from . import Image, ImageFile from . import Image, ImageFile
branches = {
"1": False,
"2": False,
"3": False,
"4": False,
"5": False,
}
def _accept(prefix: bytes) -> bool: def _accept(prefix: bytes) -> bool:
return prefix[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04" return prefix[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04"
@ -38,14 +30,6 @@ def _accept(prefix: bytes) -> bool:
class McIdasImageFile(ImageFile.ImageFile): class McIdasImageFile(ImageFile.ImageFile):
branches = {
"1": False,
"2": False,
"3": False,
"4": False,
"5": False,
}
format = "MCIDAS" format = "MCIDAS"
format_description = "McIdas area file" format_description = "McIdas area file"
@ -55,7 +39,6 @@ class McIdasImageFile(ImageFile.ImageFile):
s = self.fp.read(256) s = self.fp.read(256)
if not _accept(s) or len(s) != 256: if not _accept(s) or len(s) != 256:
McIdasImageFile.branches["1"] = True
msg = "not an McIdas area file" msg = "not an McIdas area file"
raise SyntaxError(msg) raise SyntaxError(msg)
@ -64,20 +47,16 @@ class McIdasImageFile(ImageFile.ImageFile):
# get mode # get mode
if w[11] == 1: if w[11] == 1:
McIdasImageFile.branches["2"] = True
mode = rawmode = "L" mode = rawmode = "L"
elif w[11] == 2: elif w[11] == 2:
McIdasImageFile.branches["3"] = True
# FIXME: add memory map support # FIXME: add memory map support
mode = "I" mode = "I"
rawmode = "I;16B" rawmode = "I;16B"
elif w[11] == 4: elif w[11] == 4:
McIdasImageFile.branches["4"] = True
# FIXME: add memory map support # FIXME: add memory map support
mode = "I" mode = "I"
rawmode = "I;32B" rawmode = "I;32B"
else: else:
McIdasImageFile.branches["5"] = True
msg = "unsupported McIdas format" msg = "unsupported McIdas format"
raise SyntaxError(msg) raise SyntaxError(msg)