Skip to content

Commit cf4d333

Browse files
committed
Create ImageTest.php
1 parent dfa76b1 commit cf4d333

1 file changed

Lines changed: 354 additions & 0 deletions

File tree

‎tests/ImageTest.php‎

Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
<?php
2+
/**
3+
* @author : Jakiboy
4+
* @package : FloatPHP
5+
* @subpackage : Classes Filesystem Component Tests
6+
* @version : 1.5.x
7+
* @copyright : (c) 2018 - 2025 Jihad Sinnaour <me@jihadsinnaour.com>
8+
* @link : https://floatphp.com
9+
* @license : MIT
10+
*
11+
* This file is a part of FloatPHP Framework.
12+
*/
13+
14+
declare(strict_types=1);
15+
16+
namespace FloatPHP\Tests\Classes\Filesystem;
17+
18+
use PHPUnit\Framework\TestCase;
19+
use FloatPHP\Classes\Filesystem\Image;
20+
use FloatPHP\Classes\Filesystem\File;
21+
22+
/**
23+
* Image class tests.
24+
*/
25+
final class ImageTest extends TestCase
26+
{
27+
private static string $testDir;
28+
private static string $testImage;
29+
private static string $outputDir;
30+
31+
public static function setUpBeforeClass() : void
32+
{
33+
self::$testDir = sys_get_temp_dir() . '/floatphp_image_test_' . uniqid();
34+
self::$outputDir = self::$testDir . '/output';
35+
self::$testImage = self::$testDir . '/test.png';
36+
37+
mkdir(self::$testDir, 0777, true);
38+
mkdir(self::$outputDir, 0777, true);
39+
40+
// Create a simple test image
41+
self::createTestImage();
42+
}
43+
44+
public static function tearDownAfterClass() : void
45+
{
46+
self::cleanupTestFiles();
47+
}
48+
49+
/**
50+
* Create a simple test image for testing.
51+
*/
52+
private static function createTestImage() : void
53+
{
54+
if ( !extension_loaded('gd') ) {
55+
self::markTestSkipped('GD extension not available');
56+
return;
57+
}
58+
59+
$image = imagecreatetruecolor(200, 150);
60+
$color = imagecolorallocate($image, 255, 0, 0); // Red
61+
imagefill($image, 0, 0, $color);
62+
imagepng($image, self::$testImage);
63+
imagedestroy($image);
64+
}
65+
66+
/**
67+
* Clean up test files.
68+
*/
69+
private static function cleanupTestFiles() : void
70+
{
71+
if ( is_dir(self::$testDir) ) {
72+
$files = scandir(self::$testDir);
73+
foreach ($files as $file) {
74+
if ( $file !== '.' && $file !== '..' ) {
75+
$path = self::$testDir . '/' . $file;
76+
if ( is_dir($path) ) {
77+
$subFiles = scandir($path);
78+
foreach ($subFiles as $subFile) {
79+
if ( $subFile !== '.' && $subFile !== '..' ) {
80+
unlink($path . '/' . $subFile);
81+
}
82+
}
83+
rmdir($path);
84+
} else {
85+
unlink($path);
86+
}
87+
}
88+
}
89+
rmdir(self::$testDir);
90+
}
91+
}
92+
93+
/**
94+
* Test image MIME validation.
95+
*/
96+
public function testIsMime() : void
97+
{
98+
if ( !extension_loaded('gd') ) {
99+
$this->markTestSkipped('GD extension not available');
100+
}
101+
102+
$this->assertTrue(Image::isMime(self::$testImage));
103+
104+
// Create a non-image file
105+
$textFile = self::$testDir . '/test.txt';
106+
file_put_contents($textFile, 'This is not an image');
107+
$this->assertFalse(Image::isMime($textFile));
108+
}
109+
110+
/**
111+
* Test format support checking.
112+
*/
113+
public function testIsFormatSupported() : void
114+
{
115+
$this->assertTrue(Image::isFormatSupported('image/jpeg'));
116+
$this->assertTrue(Image::isFormatSupported('image/png'));
117+
$this->assertTrue(Image::isFormatSupported('image/gif'));
118+
$this->assertFalse(Image::isFormatSupported('image/tiff'));
119+
$this->assertFalse(Image::isFormatSupported('text/plain'));
120+
}
121+
122+
/**
123+
* Test getting supported formats.
124+
*/
125+
public function testGetSupportedFormats() : void
126+
{
127+
$formats = Image::getSupportedFormats();
128+
129+
$this->assertIsArray($formats);
130+
$this->assertContains('image/jpeg', $formats);
131+
$this->assertContains('image/png', $formats);
132+
$this->assertContains('image/gif', $formats);
133+
}
134+
135+
/**
136+
* Test getting image information.
137+
*/
138+
public function testGetInfo() : void
139+
{
140+
if ( !extension_loaded('gd') ) {
141+
$this->markTestSkipped('GD extension not available');
142+
}
143+
144+
$info = Image::getInfo(self::$testImage);
145+
146+
$this->assertIsArray($info);
147+
$this->assertEquals(200, $info['width']);
148+
$this->assertEquals(150, $info['height']);
149+
$this->assertEquals('image/png', $info['format']);
150+
}
151+
152+
/**
153+
* Test basic image resizing.
154+
*/
155+
public function testResize() : void
156+
{
157+
if ( !extension_loaded('gd') ) {
158+
$this->markTestSkipped('GD extension not available');
159+
}
160+
161+
$output = self::$outputDir . '/resized.png';
162+
$result = Image::resize(self::$testImage, 100, 75, [
163+
'output' => $output
164+
]);
165+
166+
$this->assertTrue($result);
167+
$this->assertTrue(file_exists($output));
168+
169+
$info = Image::getInfo($output);
170+
$this->assertEquals(100, $info['width']);
171+
$this->assertEquals(75, $info['height']);
172+
}
173+
174+
/**
175+
* Test thumbnail creation.
176+
*/
177+
public function testThumbnail() : void
178+
{
179+
if ( !extension_loaded('gd') ) {
180+
$this->markTestSkipped('GD extension not available');
181+
}
182+
183+
$output = self::$outputDir . '/thumbnail.png';
184+
$result = Image::thumbnail(self::$testImage, 50, $output);
185+
186+
$this->assertTrue($result);
187+
$this->assertTrue(file_exists($output));
188+
189+
$info = Image::getInfo($output);
190+
$this->assertEquals(50, $info['width']);
191+
$this->assertEquals(50, $info['height']);
192+
}
193+
194+
/**
195+
* Test image rotation.
196+
*/
197+
public function testRotate() : void
198+
{
199+
if ( !extension_loaded('gd') || !function_exists('imagerotate') ) {
200+
$this->markTestSkipped('GD extension or imagerotate function not available');
201+
}
202+
203+
$output = self::$outputDir . '/rotated.png';
204+
$result = Image::rotate(self::$testImage, 90, $output);
205+
206+
$this->assertTrue($result);
207+
$this->assertTrue(file_exists($output));
208+
209+
$info = Image::getInfo($output);
210+
// After 90-degree rotation, dimensions should be swapped
211+
$this->assertEquals(150, $info['width']);
212+
$this->assertEquals(200, $info['height']);
213+
}
214+
215+
/**
216+
* Test image format conversion.
217+
*/
218+
public function testConvert() : void
219+
{
220+
if ( !extension_loaded('gd') ) {
221+
$this->markTestSkipped('GD extension not available');
222+
}
223+
224+
$output = self::$outputDir . '/converted.jpeg';
225+
$result = Image::convert(self::$testImage, 'jpeg', $output);
226+
227+
$this->assertTrue($result);
228+
$this->assertTrue(file_exists($output));
229+
230+
$info = Image::getInfo($output);
231+
$this->assertEquals('image/jpeg', $info['format']);
232+
}
233+
234+
/**
235+
* Test invalid path handling.
236+
*/
237+
public function testInvalidPath() : void
238+
{
239+
$this->expectException(\InvalidArgumentException::class);
240+
Image::resize('/nonexistent/path/image.jpg', 100, 100);
241+
}
242+
243+
/**
244+
* Test invalid dimensions.
245+
*/
246+
public function testInvalidDimensions() : void
247+
{
248+
if ( !extension_loaded('gd') ) {
249+
$this->markTestSkipped('GD extension not available');
250+
}
251+
252+
$this->expectException(\InvalidArgumentException::class);
253+
Image::resize(self::$testImage, 0, 100);
254+
}
255+
256+
/**
257+
* Test dimensions too large.
258+
*/
259+
public function testDimensionsTooLarge() : void
260+
{
261+
if ( !extension_loaded('gd') ) {
262+
$this->markTestSkipped('GD extension not available');
263+
}
264+
265+
$this->expectException(\InvalidArgumentException::class);
266+
Image::resize(self::$testImage, 20000, 20000);
267+
}
268+
269+
/**
270+
* Test unsupported format conversion.
271+
*/
272+
public function testUnsupportedFormatConversion() : void
273+
{
274+
if ( !extension_loaded('gd') ) {
275+
$this->markTestSkipped('GD extension not available');
276+
}
277+
278+
$this->expectException(\InvalidArgumentException::class);
279+
Image::convert(self::$testImage, 'tiff');
280+
}
281+
282+
/**
283+
* Test resize with crop option.
284+
*/
285+
public function testResizeWithCrop() : void
286+
{
287+
if ( !extension_loaded('gd') ) {
288+
$this->markTestSkipped('GD extension not available');
289+
}
290+
291+
$output = self::$outputDir . '/cropped.png';
292+
$result = Image::resize(self::$testImage, 100, 100, [
293+
'crop' => true,
294+
'output' => $output
295+
]);
296+
297+
$this->assertTrue($result);
298+
$this->assertTrue(file_exists($output));
299+
300+
$info = Image::getInfo($output);
301+
$this->assertEquals(100, $info['width']);
302+
$this->assertEquals(100, $info['height']);
303+
}
304+
305+
/**
306+
* Test resize with maintain aspect ratio.
307+
*/
308+
public function testResizeWithAspectRatio() : void
309+
{
310+
if ( !extension_loaded('gd') ) {
311+
$this->markTestSkipped('GD extension not available');
312+
}
313+
314+
$output = self::$outputDir . '/aspect.png';
315+
$result = Image::resize(self::$testImage, 100, 100, [
316+
'maintain_aspect' => true,
317+
'output' => $output
318+
]);
319+
320+
$this->assertTrue($result);
321+
$this->assertTrue(file_exists($output));
322+
323+
$info = Image::getInfo($output);
324+
// Should maintain aspect ratio, so not exactly 100x100
325+
$this->assertTrue($info['width'] <= 100);
326+
$this->assertTrue($info['height'] <= 100);
327+
}
328+
329+
/**
330+
* Test resize without upscaling.
331+
*/
332+
public function testResizeWithoutUpscaling() : void
333+
{
334+
if ( !extension_loaded('gd') ) {
335+
$this->markTestSkipped('GD extension not available');
336+
}
337+
338+
$output = self::$outputDir . '/no_upscale.png';
339+
340+
// Try to resize to larger dimensions with upscale disabled
341+
$result = Image::resize(self::$testImage, 400, 300, [
342+
'upscale' => false,
343+
'output' => $output
344+
]);
345+
346+
$this->assertTrue($result);
347+
$this->assertTrue(file_exists($output));
348+
349+
$info = Image::getInfo($output);
350+
// Should keep original dimensions since upscaling is disabled
351+
$this->assertEquals(200, $info['width']);
352+
$this->assertEquals(150, $info['height']);
353+
}
354+
}

0 commit comments

Comments
 (0)