Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Test Coverage for Dominant Color Images Plugin #1837

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion plugins/dominant-color-images/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// @codeCoverageIgnoreEnd


// Define required constants.
if ( defined( 'DOMINANT_COLOR_IMAGES_VERSION' ) ) {
Expand All @@ -30,3 +30,4 @@

require_once __DIR__ . '/helper.php';
require_once __DIR__ . '/hooks.php';
// @codeCoverageIgnoreEnd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
*/

use Dominant_Color_Images\Tests\TestCase;
use Imagick;
use ImagickPixel;

/**
* @coversDefaultClass Dominant_Color_Image_Editor_Imagick
*/
class Test_Dominant_Color_Image_Editor_Imagick extends TestCase {

/**
Expand All @@ -33,4 +38,164 @@ static function ( $editor ): bool {
}
);
}

/**
* @covers ::get_dominant_color
*/
public function test_failure_handling(): void {
$editor = new Dominant_Color_Image_Editor_Imagick( '/image.jpg' );
$result = $editor->get_dominant_color();
$this->assertWPError( $result );
$this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() );
}

/**
* @covers ::get_dominant_color
*/
public function test_get_dominant_color_no_image(): void {
$editor = new Dominant_Color_Image_Editor_Imagick( null );
$result = $editor->get_dominant_color();

$this->assertWPError( $result );
$this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() );
}

/**
* @covers ::get_dominant_color
*/
public function test_get_dominant_color_exception(): void {
// Creating mock that will throw an exception.
$mock = $this->getMockBuilder( Dominant_Color_Image_Editor_Imagick::class )
->onlyMethods( array( '__construct' ) )
->disableOriginalConstructor()
->getMock();

$reflection = new ReflectionClass( $mock );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $mock, new Imagick() );

$result = $mock->get_dominant_color();

$this->assertWPError( $result );
$this->assertEquals( 'image_editor_dominant_color_error', $result->get_error_code() );
}

/**
* @covers ::has_transparency
*/
public function test_has_transparency_no_image(): void {
$editor = new Dominant_Color_Image_Editor_Imagick( null );
$result = $editor->has_transparency();

$this->assertWPError( $result );
$this->assertEquals( 'image_editor_has_transparency_error_no_image', $result->get_error_code() );
}

/**
* @covers ::has_transparency
*/
public function test_has_no_transparency(): void {
$imagick = new Imagick();
$imagick->newImage( 1, 1, new ImagickPixel( 'red' ) );

$editor = new Dominant_Color_Image_Editor_Imagick( null );
$reflection = new ReflectionClass( $editor );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $editor, $imagick );

$result = $editor->has_transparency();

$this->assertFalse( $result );
}

/**
* @covers ::has_transparency
*/
public function test_has_transparency_exception(): void {
// Creating mock that will throw an exception.
$mock = $this->getMockBuilder( Dominant_Color_Image_Editor_Imagick::class )
->onlyMethods( array( '__construct' ) )
->disableOriginalConstructor()
->getMock();

$reflection = new ReflectionClass( $mock );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $mock, new Imagick() );

$result = $mock->has_transparency();

$this->assertWPError( $result );
$this->assertEquals( 'image_editor_has_transparency_error', $result->get_error_code() );
}

/**
* @covers ::get_dominant_color
*/
public function test_get_dominant_color_success(): void {
// Create a red test image.
$imagick = new Imagick();
$imagick->newImage( 1, 1, new ImagickPixel( '#FF0000' ) );

$editor = new Dominant_Color_Image_Editor_Imagick( null );
$reflection = new ReflectionClass( $editor );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $editor, $imagick );

$result = $editor->get_dominant_color();

$this->assertEquals( 'ff0000', $result );
}

/**
* @covers ::has_transparency
*/
public function test_has_transparency_with_transparency(): void {
// Create an image with transparency.
$imagick = new Imagick();
$imagick->newImage( 1, 1, new ImagickPixel( 'rgba(255,0,0,0.5)' ) );

$editor = new Dominant_Color_Image_Editor_Imagick( null );
$reflection = new ReflectionClass( $editor );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $editor, $imagick );

$result = $editor->has_transparency();

$this->assertTrue( $result );
}

/**
* @covers ::has_transparency
*/
public function test_has_transparency_no_alpha_channel_method(): void {
// Mock the Imagick object to simulate when getImageAlphaChannel method doesn't exist.
$imagick_mock = $this->getMockBuilder( Imagick::class )
->disableOriginalConstructor()
->getMock();

$imagick_mock->method( 'getImageWidth' )->willReturn( 1 );
$imagick_mock->method( 'getImageHeight' )->willReturn( 1 );

$pixel = $this->getMockBuilder( ImagickPixel::class )
->disableOriginalConstructor()
->getMock();
$pixel->method( 'getColor' )->willReturn( array( 'a' => 0 ) );

$imagick_mock->method( 'getImagePixelColor' )->willReturn( $pixel );

$editor = new Dominant_Color_Image_Editor_Imagick( null );
$reflection = new ReflectionClass( $editor );
$property = $reflection->getProperty( 'image' );
$property->setAccessible( true );
$property->setValue( $editor, $imagick_mock );

$result = $editor->has_transparency();

$this->assertFalse( $result );
}
}
109 changes: 105 additions & 4 deletions plugins/dominant-color-images/tests/test-dominant-color.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function test_dominant_color_metadata( string $image_path, array $expecte
*
* @dataProvider provider_get_dominant_color
*
* @covers ::dominant_color_get_dominant_color
* @covers helper::dominant_color_get_dominant_color
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right? The :: here refers to the global namespace.

Suggested change
* @covers helper::dominant_color_get_dominant_color
* @covers ::dominant_color_get_dominant_color

Copy link
Contributor Author

@sarthak-19 sarthak-19 Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:: refers to the global namespace, and it works for rest of the functions however, when I'm trying to generate coverage report, for the functions where I've added helper & hooks it's showing 0 coverage without file reference.

Previous Result :

  • When setting annotation to * @covers ::dominant_color_get_dominant_color & * @covers ::dominant_color_img_tag_add_dominant_color

  • helper.php

image
  • hooks.php
image

New Result :

  • When setting annotation to * @covers helper::dominant_color_get_dominant_color & * @covers hooks::dominant_color_img_tag_add_dominant_color

  • helper.php

image
  • hooks.php
image

So how should I proceed with this since helper.php & hooks.php file don't have a class so ClassName:functionName annotations will not work I also tried adding namespace to helper.php & hooks.php but it results in failing all the test cases and throws error?

cc : @westonruter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange. I don't know why that would be. I also don't understand adding hooks and helper to the beginning of those functions. They would seem to indicate there are classes called hooks and helper, which there aren't.

You're seeing this with local coverage report, but are you also seeing it with the Codecov coverage report?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They would seem to indicate there are classes called hooks and helper, which there aren't.

Exactly, still for some reason it seems to work.

You're seeing this with local coverage report, but are you also seeing it with the Codecov coverage report?

Yes, in Codecov coverage report also the same is happening.

@westonruter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thelovekesh any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sarthak-19 can you please upload the xml coverage report? maybe that can help analyze how code coverage driver is looking for things?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*
* @param string $image_path Image path.
* @param string[] $expected_color Expected color.
Expand Down Expand Up @@ -91,7 +91,7 @@ public function test_has_transparency_metadata( string $image_path, array $expec
*
* @dataProvider provider_get_dominant_color
*
* @covers ::dominant_color_get_dominant_color
* @covers helper::dominant_color_get_dominant_color
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @covers helper::dominant_color_get_dominant_color
* @covers ::dominant_color_get_dominant_color

*
* @param string $image_path Image path.
* @param string[] $expected_color Expected color.
Expand All @@ -113,7 +113,7 @@ public function test_dominant_color_has_transparency( string $image_path, array
*
* @dataProvider provider_get_dominant_color
*
* @covers ::dominant_color_img_tag_add_dominant_color
* @covers hooks::dominant_color_img_tag_add_dominant_color
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @covers hooks::dominant_color_img_tag_add_dominant_color
* @covers ::dominant_color_img_tag_add_dominant_color

*
* @param string $image_path Image path.
* @param string[] $expected_color Expected color.
Expand Down Expand Up @@ -199,7 +199,7 @@ public function data_dominant_color_img_tag_add_dominant_color_requires_proper_q
*
* @dataProvider data_provider_dominant_color_check_inline_style
*
* @covers ::dominant_color_img_tag_add_dominant_color
* @covers hooks::dominant_color_img_tag_add_dominant_color
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @covers hooks::dominant_color_img_tag_add_dominant_color
* @covers ::dominant_color_img_tag_add_dominant_color

*
* @param string $filtered_image The filtered image markup.
* Must include `src="%s" width="%d" height="%d"`.
Expand Down Expand Up @@ -408,4 +408,105 @@ public function test_dominant_color_render_generator(): void {
$this->assertStringContainsString( 'generator', $tag );
$this->assertStringContainsString( 'dominant-color-images ' . DOMINANT_COLOR_IMAGES_VERSION, $tag );
}

/**
* @covers Dominant_Color_Image_Editor_GD::get_dominant_color
*/
public function test_invalid_image_type(): void {
$editor = new Dominant_Color_Image_Editor_GD( '/invalid/type' );
$result = $editor->get_dominant_color();
$this->assertWPError( $result );
$this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() );
}

/**
* @covers Dominant_Color_Image_Editor_GD::get_dominant_color
*/
public function test_corrupted_image_file(): void {
$editor = new Dominant_Color_Image_Editor_GD( 'path/to/corrupted/file.jpg' );
$result = $editor->get_dominant_color();
$this->assertWPError( $result );
$this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() );
}

/**
* @covers ::dominant_color_add_inline_style
*/
public function test_dominant_color_add_inline_style(): void {
dominant_color_add_inline_style();

// Verify the style was registered.
global $wp_styles;
$this->assertTrue( isset( $wp_styles->registered['dominant-color-styles'] ) );

// Verify the style was enqueued.
$this->assertTrue( wp_style_is( 'dominant-color-styles', 'enqueued' ) );

// Verify the inline style was added.
$inline_styles = $wp_styles->get_data( 'dominant-color-styles', 'after' );
$this->assertNotEmpty( $inline_styles );
$this->assertStringContainsString(
'img[data-dominant-color]:not(.has-transparency) { background-color: var(--dominant-color); }',
implode( '', $inline_styles )
);
}

/**
* @covers ::dominant_color_admin_inline_style
*/
public function test_dominant_color_admin_inline_style(): void {
dominant_color_admin_inline_style();

// Verify the style was registered.
global $wp_styles;
$this->assertTrue( isset( $wp_styles->registered['dominant-color-admin-styles'] ) );

// Verify the style was enqueued.
$this->assertTrue( wp_style_is( 'dominant-color-admin-styles', 'enqueued' ) );

// Verify the inline style was added.
$inline_styles = $wp_styles->get_data( 'dominant-color-admin-styles', 'after' );
$this->assertNotEmpty( $inline_styles );
$this->assertStringContainsString(
'.wp-core-ui .attachment-preview[data-dominant-color]:not(.has-transparency) { background-color: var(--dominant-color); }',
implode( '', $inline_styles )
);
}

/**
* @covers ::dominant_color_admin_script
*/
public function test_dominant_color_admin_script(): void {
ob_start();
dominant_color_admin_script();
$output = ob_get_clean();

// Verify if script tag exists.
$this->assertStringEndsWith( '</script>', trim( $output ) );

// Verify the key elements of the script.
$this->assertStringContainsString( 'tmpl.textContent.replace', $output );
$this->assertStringContainsString( 'data-dominant-color', $output );
$this->assertStringContainsString( 'data-has-transparency', $output );
$this->assertStringContainsString( '--dominant-color', $output );
}

/**
* @covers ::dominant_color_prepare_attachment_for_js
*/
public function test_dominant_color_prepare_attachment_for_js(): void {
$attachment = self::factory()->post->create_and_get( array( 'post_type' => 'attachment' ) );

$meta = array(
'dominant_color' => 'ff0000',
'has_transparency' => true,
);

$response = dominant_color_prepare_attachment_for_js( array(), $attachment, $meta );

$this->assertArrayHasKey( 'dominantColor', $response );
$this->assertArrayHasKey( 'hasTransparency', $response );
$this->assertEquals( 'ff0000', $response['dominantColor'] );
$this->assertTrue( $response['hasTransparency'] );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ public function test_next_tag_and_get_xpath( string $document, array $open_tags,
$actual_xpath_breadcrumbs_mapping[ $xpath ] = $p->get_breadcrumbs();

$transitional_xpath = $p->get_xpath();
$this->assertRegExp(
$this->assertMatchesRegularExpression(
'#^/HTML(
/HEAD(/\*\[\d+]\[self::\w+])?
|
Expand Down
Loading