Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@
"type": "php",
"request": "launch",
"port": 9003
},
{
"name": "XDebug PHPUnit (filter)",
"type": "php",
"request": "launch",
"program": "${workspaceFolder}/vendor/bin/phpunit",
"args": ["--filter", "${input:phpunitFilter}"],
"cwd": "${workspaceFolder}",
"port": 0,
"runtimeArgs": ["-dxdebug.start_with_request=yes"],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
}
],
"inputs": [
{
"id": "phpunitFilter",
"type": "promptString",
"description": "PHPUnit --filter (test method, class, or Class::method)"
}
]
}
2 changes: 1 addition & 1 deletion bin/check-style
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
vendor/bin/phpcs --standard=phpcs.xml "$@"
XDEBUG_MODE=${XDEBUG_MODE:-off} vendor/bin/phpcs --standard=phpcs.xml "$@"
2 changes: 1 addition & 1 deletion bin/format-style
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
vendor/bin/phpcbf --standard=phpcs.xml "$@"
XDEBUG_MODE=${XDEBUG_MODE:-off} vendor/bin/phpcbf --standard=phpcs.xml "$@"
2 changes: 1 addition & 1 deletion bin/unit-tests
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
vendor/bin/phpunit test/unit $@
XDEBUG_MODE=${XDEBUG_MODE:-off} vendor/bin/phpunit test/unit "$@"
20 changes: 10 additions & 10 deletions src/class-tiny-image.php
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,8 @@ public function can_be_converted() {

/**
* Get the targeted conversion.
* If original is already converted, then we use the originals' mimetype.
* If a size is already converted, then we use that size's mimetype so
* sizes never mix formats, even when the settings changed since.
* If nothing is converted yet, we use the settings conversion settings.
*
* @since 3.6.4
Expand All @@ -635,15 +636,14 @@ private function convert_to() {
return array();
}

if ( isset( $this->sizes[ self::ORIGINAL ] ) ) {
// original is not in sizes so mimetypes are open
return $convert_settings['convert_to'];
}

$original_img_size = $this->sizes[ self::ORIGINAL ];
if ( $original_img_size->converted() ) {
// original has been convert so use that mimetype to convert to
return array( $original_img_size->meta['convert']['type'] );
foreach ( $this->sizes as $size ) {
if ( ! $size->converted() ) {
continue;
}
$type = $size->meta['convert']['type'];
if ( in_array( $type, array( 'image/avif', 'image/webp' ), true ) ) {
return array( $type );
}
}

return $convert_settings['convert_to'];
Expand Down
145 changes: 145 additions & 0 deletions test/unit/TinyImageTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use function PHPUnit\Framework\assertEquals;

require_once dirname( __FILE__ ) . '/TinyTestCase.php';

class Tiny_Image_Test extends Tiny_TestCase {
Expand Down Expand Up @@ -367,4 +369,147 @@ public function test_conversion_same_mimetype()
$this->assertEquals(array('image/webp'), $compress_calls[1]['convert_to']);
}

/**
* A size added after the original was converted gets the original's format.
*/
public function test_later_compression_converts_to_format_of_earlier_conversion()
{
$this->wp->addOption('tinypng_convert_format', array(
'convert' => 'on',
'convert_to' => 'smallest',
));
$this->wp->addOption('tinypng_sizes', array(
Tiny_Image::ORIGINAL => 'on',
'thumbnail' => 'on',
));
$this->wp->stub('get_post_mime_type', function () {
return 'image/png';
});
$this->wp->createImages(array());

$settings = new Tiny_Settings();
$mock_compressor = $this->createMock(Tiny_Compress::class);
$convert_to_calls = array();
$mock_compressor->method('compress_file')
->willReturnCallback(function ($file, $resize, $preserve, $convert_to) use (&$convert_to_calls) {
$convert_to_calls[] = $convert_to;
return array(
'input' => array('size' => 12345),
'output' => array('size' => 12345, 'type' => 'image/png'),
'convert' => array('type' => 'image/avif', 'size' => 9000, 'path' => 'vfs://root/test.avif'),
);
});
$settings->set_compressor($mock_compressor);

// first run: only the original exists
$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->compress();

// second run: a thumbnail has been added since
$this->wp->createImage(1000, '14/01', 'test-thumbnail.png');
$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->compress();


assertEquals(array('image/avif', 'image/webp'), $convert_to_calls[0], 'original can be converted to avif and webp');
assertEquals(array('image/avif'), $convert_to_calls[1], 'original output was avif so expect subsequent sizes to avif');
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

public function test_first_conversion_decides_mimetype()
{
$this->wp->addOption('tinypng_convert_format', array(
'convert' => 'on',
'convert_to' => 'smallest',
));

// first run only compresses thumbnails
$this->wp->addOption('tinypng_sizes', array(
Tiny_Image::ORIGINAL => 'on',
'thumbnail' => 'on',
));

$this->wp->createImage(1000, '14/01', 'test-thumbnail.png');

$this->wp->stub('get_post_mime_type', function () {
return 'image/png';
});

$convert_to_calls = array();
$mock_compressor = $this->createMock(Tiny_Compress::class);
$mock_compressor->method('compress_file')
->willReturnCallback(function ($file, $resize, $preserve, $convert_to) use (&$convert_to_calls) {
$convert_to_calls[] = array(
'format' => $convert_to,
'size' => $file,
);
return array(
'input' => array('size' => 1000),
'output' => array('size' => 500, 'type' => 'image/png'),
'convert' => array('type' => 'image/avif', 'size' => 300, 'path' => 'vfs://root/test_100x100.avif'),
);
});

$settings = new Tiny_Settings();
$settings->set_compressor($mock_compressor);

$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->compress();

// first run only compresses thumbnails
assertEquals($convert_to_calls[0], array(
'size' => "vfs://root/wp-content/uploads/14/01/test-thumbnail.png",
'format' => array('image/avif', 'image/webp')
), 'first run should be either webp or avif');

// second run: original added
$this->wp->createImage(2500, '14/01', 'test.png');
$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->compress();

// second run compresses the original forced on avif
assertEquals($convert_to_calls[1], array(
'size' => "vfs://root/wp-content/uploads/14/01/test.png",
'format' => array('image/avif')
), 'thumbnail was avif, so original should only have avif');
}

/**
* Marking as compressed records the original's own mimetype as conversion,
* a size added afterwards must not be converted to that mimetype.
*/
public function test_compression_after_mark_as_compressed_uses_conversion_settings()
{
$this->wp->addOption('tinypng_convert_format', array(
'convert' => 'on',
'convert_to' => 'smallest',
));
$this->wp->addOption('tinypng_sizes', array(
Tiny_Image::ORIGINAL => 'on',
'thumbnail' => 'on',
));
$this->wp->stub('get_post_mime_type', function () {
return 'image/png';
});
$this->wp->createImages(array());

$settings = new Tiny_Settings();
$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->mark_as_compressed();

$mock_compressor = $this->createMock(Tiny_Compress::class);

// assert that
$mock_compressor->expects($this->once())
->method('compress_file')
->with($this->anything(), $this->anything(), $this->anything(), array('image/avif', 'image/webp'))
->willReturn(array(
'input' => array('size' => 1000),
'output' => array('size' => 1000, 'type' => 'image/png'),
));
$settings->set_compressor($mock_compressor);

$this->wp->createImage(1000, '14/01', 'test-thumbnail.png');
$tinyimg = new Tiny_Image($settings, 999, $this->wp->getTestMetadata());
$tinyimg->compress();
}
}
2 changes: 2 additions & 0 deletions test/unit/TinyMigrateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class Tiny_Migrate_Test extends Tiny_TestCase
public function set_up()
{
parent::set_up();
// reduce test noise by swalloing error_log
$this->iniSet('error_log', '/dev/null');
$this->wp->stub('query', function() {
return 1;
});
Expand Down
Loading