diff --git a/phpunit/block-supports/elements-test.php b/phpunit/block-supports/elements-test.php new file mode 100644 index 00000000000000..efea11887b620b --- /dev/null +++ b/phpunit/block-supports/elements-test.php @@ -0,0 +1,305 @@ +test_block_name = null; + } + + public function tear_down() { + WP_Style_Engine_CSS_Rules_Store_Gutenberg::remove_all_stores(); + unregister_block_type( $this->test_block_name ); + $this->test_block_name = null; + parent::tear_down(); + } + + /** + * Registers a test block type with the provided color block supports. + * + * @param array $color_settings The color block support settings used for elements. + */ + public function register_block_with_color_settings( $color_settings ) { + $this->test_block_name = 'test/element-block-supports'; + + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'attributes' => array( + 'style' => array( + 'type' => 'object', + ), + ), + 'supports' => array( + 'color' => $color_settings, + ), + ) + ); + } + + /** + * Tests that elements block support applies the correct classname. + * + * @covers ::gutenberg_render_elements_support + * + * @dataProvider data_elements_block_support_class + * + * @param array $color_settings The color block support settings used for elements support. + * @param array $elements_styles The elements styles within the block attributes. + * @param string $block_markup Original block markup. + * @param string $expected_markup Resulting markup after application of elements block support. + */ + public function test_elements_block_support_class( $color_settings, $elements_styles, $block_markup, $expected_markup ) { + $this->register_block_with_color_settings( $color_settings ); + + $block = array( + 'blockName' => $this->test_block_name, + 'attrs' => array( + 'style' => array( + 'elements' => $elements_styles, + ), + ), + ); + + $actual = gutenberg_render_elements_support( $block_markup, $block ); + + $this->assertMatchesRegularExpression( + $expected_markup, + $actual, + 'Elements block wrapper markup should be correct' + ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_elements_block_support_class() { + $color_styles = array( + 'text' => 'var:preset|color|vivid-red', + 'background' => '#fff', + ); + + return array( + 'button element styles with serialization skipped' => array( + 'color_settings' => array( + 'button' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'button' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'link element styles with serialization skipped' => array( + 'color_settings' => array( + 'link' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'link' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'heading element styles with serialization skipped' => array( + 'color_settings' => array( + 'heading' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'heading' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'button element styles apply class to wrapper' => array( + 'color_settings' => array( 'button' => true ), + 'elements_styles' => array( + 'button' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'link element styles apply class to wrapper' => array( + 'color_settings' => array( 'link' => true ), + 'elements_styles' => array( + 'link' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'heading element styles apply class to wrapper' => array( + 'color_settings' => array( 'heading' => true ), + 'elements_styles' => array( + 'heading' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'element styles apply class to wrapper when it has other classes' => array( + 'color_settings' => array( 'link' => true ), + 'elements_styles' => array( + 'link' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + 'element styles apply class to wrapper when it has other attributes' => array( + 'color_settings' => array( 'link' => true ), + 'elements_styles' => array( + 'link' => array( 'color' => $color_styles ), + ), + 'block_markup' => '

Hello WordPress!

', + 'expected_markup' => '/^

Hello WordPress<\/a>!<\/p>$/', + ), + ); + } + + /** + * Tests that elements block support generates appropriate styles. + * + * @covers ::gutenberg_render_elements_support_styles + * + * @dataProvider data_elements_block_support_styles + * + * @param mixed $color_settings The color block support settings used for elements support. + * @param mixed $elements_styles The elements styles within the block attributes. + * @param string $expected_styles Expected styles enqueued by the style engine. + */ + public function test_elements_block_support_styles( $color_settings, $elements_styles, $expected_styles ) { + $this->register_block_with_color_settings( $color_settings ); + + $block = array( + 'blockName' => $this->test_block_name, + 'attrs' => array( + 'style' => array( + 'elements' => $elements_styles, + ), + ), + ); + + gutenberg_render_elements_support_styles( null, $block ); + $actual_stylesheet = gutenberg_style_engine_get_stylesheet_from_context( 'block-supports' ); + + $this->assertMatchesRegularExpression( + $expected_styles, + $actual_stylesheet, + 'Elements style rules output should be correct' + ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_elements_block_support_styles() { + $color_styles = array( + 'text' => 'var:preset|color|vivid-red', + 'background' => '#fff', + ); + $color_css_rules = preg_quote( '{color:var(--wp--preset--color--vivid-red);background-color:#fff;}' ); + + return array( + 'button element styles are not applied if serialization is skipped' => array( + 'color_settings' => array( + 'button' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'button' => array( 'color' => $color_styles ), + ), + 'expected_styles' => '/^$/', + ), + 'link element styles are not applied if serialization is skipped' => array( + 'color_settings' => array( + 'link' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'link' => array( + 'color' => $color_styles, + ':hover' => array( + 'color' => $color_styles, + ), + ), + ), + 'expected_styles' => '/^$/', + ), + 'heading element styles are not applied if serialization is skipped' => array( + 'color_settings' => array( + 'heading' => true, + '__experimentalSkipSerialization' => true, + ), + 'elements_styles' => array( + 'heading' => array( 'color' => $color_styles ), + 'h1' => array( 'color' => $color_styles ), + 'h2' => array( 'color' => $color_styles ), + 'h3' => array( 'color' => $color_styles ), + 'h4' => array( 'color' => $color_styles ), + 'h5' => array( 'color' => $color_styles ), + 'h6' => array( 'color' => $color_styles ), + ), + 'expected_styles' => '/^$/', + ), + 'button element styles are applied' => array( + 'color_settings' => array( 'button' => true ), + 'elements_styles' => array( + 'button' => array( 'color' => $color_styles ), + ), + 'expected_styles' => '/^.wp-elements-[a-f0-9]{32} .wp-element-button, .wp-elements-[a-f0-9]{32} .wp-block-button__link' . $color_css_rules . '$/', + ), + 'link element styles are applied' => array( + 'color_settings' => array( 'link' => true ), + 'elements_styles' => array( + 'link' => array( + 'color' => $color_styles, + ':hover' => array( + 'color' => $color_styles, + ), + ), + ), + 'expected_styles' => '/^.wp-elements-[a-f0-9]{32} a' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} a:hover' . $color_css_rules . '$/', + ), + 'generic heading element styles are applied' => array( + 'color_settings' => array( 'heading' => true ), + 'elements_styles' => array( + 'heading' => array( 'color' => $color_styles ), + ), + 'expected_styles' => '/^.wp-elements-[a-f0-9]{32} h1, .wp-elements-[a-f0-9]{32} h2, .wp-elements-[a-f0-9]{32} h3, .wp-elements-[a-f0-9]{32} h4, .wp-elements-[a-f0-9]{32} h5, .wp-elements-[a-f0-9]{32} h6' . $color_css_rules . '$/', + ), + 'individual heading element styles are applied' => array( + 'color_settings' => array( 'heading' => true ), + 'elements_styles' => array( + 'h1' => array( 'color' => $color_styles ), + 'h2' => array( 'color' => $color_styles ), + 'h3' => array( 'color' => $color_styles ), + 'h4' => array( 'color' => $color_styles ), + 'h5' => array( 'color' => $color_styles ), + 'h6' => array( 'color' => $color_styles ), + ), + 'expected_styles' => '/^.wp-elements-[a-f0-9]{32} h1' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} h2' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} h3' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} h4' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} h5' . $color_css_rules . + '.wp-elements-[a-f0-9]{32} h6' . $color_css_rules . '$/', + ), + ); + } +}