mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
The Interactivity API enables WordPress developers to create dynamic and interactive web experiences with ease using a set of special HTML attributes called directives. Please refer to the [Interactivity API proposal](https://make.wordpress.org/core/2023/03/30/proposal-the-interactivity-api-a-better-developer-experience-in-building-interactive-blocks/) for further details. It syncs the changes from the Gutenberg plugin: https://github.com/WordPress/gutenberg/pull/58066. Fixes #60356. Props luisherranz, jonsurrell, swissspidy, westonruter, gziolo. git-svn-id: https://develop.svn.wordpress.org/trunk@57563 602fd350-edb4-49c9-b593-d223f7449a82
446 lines
16 KiB
PHP
446 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* Unit tests covering the data_wp_style_processor functionality of the
|
|
* WP_Interactivity_API class.
|
|
*
|
|
* @package WordPress
|
|
* @subpackage Interactivity API
|
|
*
|
|
* @since 6.5.0
|
|
*
|
|
* @group interactivity-api
|
|
*/
|
|
class Tests_WP_Interactivity_API_WP_Style extends WP_UnitTestCase {
|
|
/**
|
|
* Instance of WP_Interactivity_API.
|
|
*
|
|
* @var WP_Interactivity_API
|
|
*/
|
|
protected $interactivity;
|
|
|
|
/**
|
|
* Set up.
|
|
*/
|
|
public function set_up() {
|
|
parent::set_up();
|
|
$this->interactivity = new WP_Interactivity_API();
|
|
$this->interactivity->state(
|
|
'myPlugin',
|
|
array(
|
|
'green' => 'green',
|
|
'false' => false,
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Invokes the private `merge_style_property` method of WP_Interactivity_API
|
|
* class.
|
|
*
|
|
* @param string $style_attribute_value The current style attribute value.
|
|
* @param string $style_property_name The style property name to set.
|
|
* @param string|false|null $style_property_value The value to set for the style property. With false, null or an
|
|
* empty string, it removes the style property.
|
|
* @return string The new style attribute value after the specified property has been added, updated or removed.
|
|
*/
|
|
private function merge_style_property( $style_attribute_value, $style_property_name, $style_property_value ) {
|
|
$evaluate = new ReflectionMethod( $this->interactivity, 'merge_style_property' );
|
|
$evaluate->setAccessible( true );
|
|
return $evaluate->invokeArgs( $this->interactivity, array( $style_attribute_value, $style_property_name, $style_property_value ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that `merge_style_property` correctly sets style properties.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::merge_style_property
|
|
*/
|
|
public function test_merge_style_property_sets_properties() {
|
|
// Adds property on empty style attribute.
|
|
$result = $this->merge_style_property( '', 'color', 'green' );
|
|
$this->assertEquals( 'color:green;', $result );
|
|
|
|
// Changes style property when there is an existing property.
|
|
$result = $this->merge_style_property( 'color:red;', 'color', 'green' );
|
|
$this->assertEquals( 'color:green;', $result );
|
|
|
|
// Adds a new property when the existing one does not match.
|
|
$result = $this->merge_style_property( 'color:red;', 'background', 'blue' );
|
|
$this->assertEquals( 'color:red;background:blue;', $result );
|
|
|
|
// Handles multiple existing properties.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'color', 'green' );
|
|
$this->assertEquals( 'margin:5px;color:green;', $result );
|
|
|
|
// Adds a new property when multiple existing properties do not match.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'padding', '10px' );
|
|
$this->assertEquals( 'color:red;margin:5px;padding:10px;', $result );
|
|
|
|
// Removes whitespaces in all properties.
|
|
$result = $this->merge_style_property( ' color : red; margin : 5px; ', 'padding', ' 10px ' );
|
|
$this->assertEquals( 'color:red;margin:5px;padding:10px;', $result );
|
|
|
|
// Updates a property when it's not the first one in the value.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'margin', '15px' );
|
|
$this->assertEquals( 'color:red;margin:15px;', $result );
|
|
|
|
// Adds missing trailing semicolon.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px', 'padding', '10px' );
|
|
$this->assertEquals( 'color:red;margin:5px;padding:10px;', $result );
|
|
|
|
// Doesn't add double semicolons.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'padding', '10px;' );
|
|
$this->assertEquals( 'color:red;margin:5px;padding:10px;', $result );
|
|
|
|
// Handles empty properties in the input.
|
|
$result = $this->merge_style_property( 'color:red;;margin:5px;;', 'padding', '10px' );
|
|
$this->assertEquals( 'color:red;margin:5px;padding:10px;', $result );
|
|
|
|
// Moves the modified property to the end.
|
|
$result = $this->merge_style_property( 'border-style: dashed; border: 3px solid red;', 'border-style', 'inset' );
|
|
$this->assertEquals( 'border:3px solid red;border-style:inset;', $result );
|
|
}
|
|
|
|
/**
|
|
* Tests that `merge_style_property` works correctly with falsy values,
|
|
* removing or ignoring them as appropriate.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::merge_style_property
|
|
*/
|
|
public function test_merge_style_property_with_falsy_values() {
|
|
// Removes a property with an empty string.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'color', '' );
|
|
$this->assertEquals( 'margin:5px;', $result );
|
|
|
|
// Removes a property with null.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'color', null );
|
|
$this->assertEquals( 'margin:5px;', $result );
|
|
|
|
// Removes a property with false.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'color', false );
|
|
$this->assertEquals( 'margin:5px;', $result );
|
|
|
|
// Removes a property with 0.
|
|
$result = $this->merge_style_property( 'color:red;margin:5px;', 'color', 0 );
|
|
$this->assertEquals( 'margin:5px;', $result );
|
|
|
|
// It doesn't add a new property with an empty string.
|
|
$result = $this->merge_style_property( 'color:red;', 'padding', '' );
|
|
$this->assertEquals( 'color:red;', $result );
|
|
|
|
// It doesn't add a new property with null.
|
|
$result = $this->merge_style_property( 'color:red;', 'padding', null );
|
|
$this->assertEquals( 'color:red;', $result );
|
|
|
|
// It doesn't add a new property with false.
|
|
$result = $this->merge_style_property( 'color:red;', 'padding', false );
|
|
$this->assertEquals( 'color:red;', $result );
|
|
|
|
// It doesn't add a new property with 0.
|
|
$result = $this->merge_style_property( 'color:red;', 'padding', 0 );
|
|
$this->assertEquals( 'color:red;', $result );
|
|
}
|
|
|
|
/**
|
|
* Invokes the `process_directives` method of WP_Interactivity_API class.
|
|
*
|
|
* @param string $html The HTML that needs to be processed.
|
|
* @return array An array containing an instance of the WP_HTML_Tag_Processor and the processed HTML.
|
|
*/
|
|
private function process_directives( $html ) {
|
|
$new_html = $this->interactivity->process_directives( $html );
|
|
$p = new WP_HTML_Tag_Processor( $new_html );
|
|
$p->next_tag();
|
|
return array( $p, $new_html );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive sets a style attribute with
|
|
* correct property and value.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_sets_style_attribute() {
|
|
$html = '<div data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive applies multiple style properties
|
|
* correctly.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_sets_multiple_style_properties() {
|
|
$html = '
|
|
<div
|
|
data-wp-style--color="myPlugin::state.green"
|
|
data-wp-style--background="myPlugin::state.green"
|
|
>Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;background:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive correctly handles different style
|
|
* property values.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_sets_multiple_style_properties_with_different_values() {
|
|
$html = '
|
|
<div
|
|
data-wp-style--color="myPlugin::state.green"
|
|
data-wp-style--background="myPlugin::state.false"
|
|
>Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
|
|
$html = '
|
|
<div
|
|
style="background:red;"
|
|
data-wp-style--color="myPlugin::state.green"
|
|
data-wp-style--background="myPlugin::state.false"
|
|
>Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive sets a new style property when
|
|
* another already exists.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_sets_style_property_when_style_attribute_exists() {
|
|
$html = '<div style="padding:10px;" data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive overwrites an existing style
|
|
* property with a new value.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_overwrites_style_property_when_style_property_exists() {
|
|
$html = '<div style="color:red;" data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive doesn't add a style property when
|
|
* the directive value is false.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_add_style_attribute_on_false() {
|
|
$html = '<div data-wp-style--color="myPlugin::state.false">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive doesn't modify existing style
|
|
* properties when directive value is false.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_add_style_property_on_false() {
|
|
$html = '<div style="padding:10px;" data-wp-style--color="myPlugin::state.false">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive keeps an existing style property
|
|
* with a matching value.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_keeps_style_property_when_style_property_exists() {
|
|
$html = '<div style="color:green;" data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive maintains style properties even
|
|
* when they aren't the only ones present.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_keeps_style_property_when_style_property_exists_and_is_not_the_only_one() {
|
|
$html = '<div style="padding:10px;color:green;" data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive removes the style attribute when
|
|
* it contains only one property which is being removed.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_removes_style_attribute_when_style_property_exists_and_is_the_only_one() {
|
|
$html = '<div style="color:green;" data-wp-style--color="myPlugin::state.false">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive removes a style property when it's
|
|
* not the only one present and the directive value is false.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_removes_style_property_when_style_property_exists_and_is_not_the_only_one() {
|
|
$html = '<div style="padding:10px;color:green;" data-wp-style--color="myPlugin::state.false">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive does not remove an empty style
|
|
* attribute.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_remove_empty_style_attribute() {
|
|
$html = '<div style data-wp-style--color="myPlugin::state.false">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertTrue( $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive does not change the style
|
|
* attribute when the directive suffix is empty.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_change_style_attribute_with_empty_directive_suffix() {
|
|
$html = '<div style="padding:10px;" data-wp-style="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive does not change the style
|
|
* attribute when the value of the directive is empty.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_change_style_attribute_with_empty_value() {
|
|
$html = '<div style="padding:10px" data-wp-style--color="">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive doesn't apply changes if no value
|
|
* is provided for the style property.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_change_style_attribute_without_value() {
|
|
$html = '<div style="padding: 10px;" data-wp-style--color>Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive functions correctly with multiple
|
|
* identical directives.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_works_with_multiple_directives() {
|
|
$html = '<div data-wp-style--color="myPlugin::state.green" data-wp-style--color="myPlugin::state.green">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive doesn't apply any changes when the
|
|
* state value is true.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_do_anything_on_true_values() {
|
|
$this->interactivity->state( 'myPlugin', array( 'true' => true ) );
|
|
$html = '<div data-wp-style--color="myPlugin::state.text">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
}
|
|
|
|
/**
|
|
* Tests that the `data-wp-style` directive doesn't add a style property for
|
|
* various falsy values in the state.
|
|
*
|
|
* @ticket 60356
|
|
*
|
|
* @covers ::process_directives
|
|
*/
|
|
public function test_wp_style_doesnt_add_style_property_on_falsy_values() {
|
|
$this->interactivity->state( 'myPlugin', array( 'text' => '' ) );
|
|
$html = '<div data-wp-style--color="myPlugin::state.text">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
|
|
$this->interactivity->state( 'myPlugin', array( 'array' => array() ) );
|
|
$html = '<div data-wp-style--color="myPlugin::state.array">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
|
|
$this->interactivity->state( 'myPlugin', array( 'number' => 0 ) );
|
|
$html = '<div data-wp-style--color="myPlugin::state.number">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
|
|
$this->interactivity->state( 'myPlugin', array( 'null' => null ) );
|
|
$html = '<div data-wp-style--color="myPlugin::state.null">Text</div>';
|
|
list($p) = $this->process_directives( $html );
|
|
$this->assertNull( $p->get_attribute( 'style' ) );
|
|
}
|
|
}
|