|
3 | 3 | """ |
4 | 4 | import os |
5 | 5 | import unittest |
6 | | -from unittest.mock import MagicMock, patch |
| 6 | +from unittest.mock import patch |
7 | 7 |
|
8 | 8 | from PIL import Image, ImageDraw |
9 | 9 |
|
10 | 10 | import sys |
| 11 | + |
11 | 12 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
12 | 13 |
|
13 | 14 | from image_processor import ImageProcessor |
14 | 15 |
|
15 | 16 |
|
16 | 17 | class TestImageProcessor(unittest.TestCase): |
17 | 18 | """Tests for the ImageProcessor class""" |
18 | | - |
| 19 | + |
19 | 20 | def setUp(self): |
20 | 21 | """Set up test fixtures""" |
21 | 22 | self.processor = ImageProcessor() |
22 | | - |
| 23 | + |
23 | 24 | # Create test images of different dimensions |
24 | 25 | self.square_image = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) |
25 | 26 | self.wide_image = Image.new('RGBA', (200, 100), (0, 255, 0, 255)) |
26 | 27 | self.tall_image = Image.new('RGBA', (100, 200), (0, 0, 255, 255)) |
27 | | - |
| 28 | + |
28 | 29 | def test_crop_to_square_already_square(self): |
29 | 30 | """Test cropping an already square image""" |
30 | 31 | result = self.processor.crop_to_square(self.square_image) |
31 | 32 | self.assertEqual(result.size, (100, 100)) |
32 | | - |
| 33 | + |
33 | 34 | def test_crop_to_square_wide_image(self): |
34 | 35 | """Test cropping a wide image to square""" |
35 | 36 | result = self.processor.crop_to_square(self.wide_image) |
36 | 37 | self.assertEqual(result.size, (100, 100)) |
37 | | - |
| 38 | + |
38 | 39 | def test_crop_to_square_tall_image(self): |
39 | 40 | """Test cropping a tall image to square""" |
40 | 41 | result = self.processor.crop_to_square(self.tall_image) |
41 | 42 | self.assertEqual(result.size, (100, 100)) |
42 | | - |
| 43 | + |
43 | 44 | def test_resize_image(self): |
44 | 45 | """Test resizing an image""" |
45 | 46 | result = self.processor.resize_image(self.square_image, (50, 50)) |
46 | 47 | self.assertEqual(result.size, (50, 50)) |
47 | | - |
| 48 | + |
48 | 49 | def test_apply_gradient_fade(self): |
49 | 50 | """Test applying gradient fade""" |
50 | 51 | # Create a test image |
51 | 52 | image = Image.new('RGBA', (100, 100), (255, 255, 255, 255)) |
52 | | - |
| 53 | + |
53 | 54 | # Apply fade to bottom 20 pixels |
54 | 55 | result = self.processor.apply_gradient_fade(image, 20) |
55 | | - |
| 56 | + |
56 | 57 | # Check size hasn't changed |
57 | 58 | self.assertEqual(result.size, (100, 100)) |
58 | | - |
| 59 | + |
59 | 60 | # Check that alpha channel has been modified |
60 | 61 | # Top part should still be fully opaque |
61 | 62 | self.assertEqual(result.getpixel((50, 10))[3], 255) |
62 | | - |
| 63 | + |
63 | 64 | # Bottom part should have reduced opacity |
64 | 65 | self.assertLess(result.getpixel((50, 90))[3], 255) |
65 | | - |
| 66 | + |
66 | 67 | def test_create_background(self): |
67 | 68 | """Test creating a gradient background""" |
68 | 69 | # Create a simple gradient |
69 | | - result = self.processor.create_background((100, 100), "#FF0000", "#0000FF") |
70 | | - |
| 70 | + result = self.processor.create_background((100, 100), "#FF0000", |
| 71 | + "#0000FF") |
| 72 | + |
71 | 73 | # Check size |
72 | 74 | self.assertEqual(result.size, (100, 100)) |
73 | | - |
| 75 | + |
74 | 76 | # Check gradient - top should be reddish, bottom should be bluish |
75 | | - r, g, b, a = result.getpixel((50, 10)) |
76 | | - self.assertGreater(r, b) # More red than blue at top |
77 | | - |
78 | | - r, g, b, a = result.getpixel((50, 90)) |
79 | | - self.assertGreater(b, r) # More blue than red at bottom |
80 | | - |
| 77 | + r, _, b, _ = result.getpixel((50, 10)) |
| 78 | + self.assertGreater(r, b) |
| 79 | + |
| 80 | + r, _, b, _ = result.getpixel((50, 90)) |
| 81 | + self.assertGreater(b, r) |
| 82 | + |
81 | 83 | @patch('image_processor.logger') |
82 | 84 | def test_create_background_with_error(self, mock_logger): |
83 | 85 | """Test creating a background with invalid color values""" |
84 | 86 | # Create a background with invalid color |
85 | | - result = self.processor.create_background((100, 100), "invalid", "#0000FF") |
86 | | - |
| 87 | + result = self.processor.create_background((100, 100), "invalid", |
| 88 | + "#0000FF") |
| 89 | + |
87 | 90 | # Should fall back to solid color |
88 | 91 | self.assertEqual(result.size, (100, 100)) |
89 | | - |
| 92 | + |
90 | 93 | # Logger should have recorded the error |
91 | 94 | mock_logger.error.assert_called_once() |
92 | | - |
| 95 | + |
93 | 96 | def test_position_logo(self): |
94 | 97 | """Test positioning a logo on an image""" |
95 | | - # Create base image and logo |
| 98 | + |
96 | 99 | base_image = Image.new('RGBA', (200, 200), (255, 255, 255, 255)) |
97 | 100 | logo = Image.new('RGBA', (50, 25), (0, 0, 0, 255)) |
98 | | - |
99 | | - # Position logo with 10px margin |
| 101 | + |
100 | 102 | result = self.processor.position_logo(base_image, logo, 10, 0.25) |
101 | | - |
102 | | - # Check size hasn't changed |
| 103 | + |
103 | 104 | self.assertEqual(result.size, (200, 200)) |
104 | | - |
| 105 | + |
105 | 106 | # Logo should be in top-right corner |
106 | 107 | # Base image is white, logo is black, so checking for non-white pixels |
107 | 108 | # at the expected logo position |
108 | | - |
| 109 | + |
109 | 110 | # Logo width should be 25% of base image width = 50px |
110 | 111 | # Logo should be at position (200 - 50 - 10, 10) = (140, 10) |
111 | 112 | # Check pixel near the logo center |
112 | | - r, g, b, a = result.getpixel((150, 15)) |
113 | | - self.assertLess(r + g + b, 100) # Should be dark (black logo) |
| 113 | + r, g, b, _ = result.getpixel((150, 15)) |
| 114 | + self.assertLess(r + g + b, 100) |
114 | 115 |
|
115 | 116 |
|
116 | 117 | if __name__ == '__main__': |
|
0 commit comments