@@ -7731,4 +7731,284 @@ public function test_block_custom_states_ignores_non_whitelisted() {
77317731 $ this ->assertStringNotContainsString ( '-current ' , $ stylesheet_unsupported );
77327732 $ this ->assertStringNotContainsString ( 'current-menu-item ' , $ stylesheet_unsupported );
77337733 }
7734+
7735+ /**
7736+ * Tests that append_to_selector correctly appends to single and
7737+ * compound (comma-separated) selectors.
7738+ *
7739+ * @ticket 65533
7740+ *
7741+ * @dataProvider data_append_to_selector
7742+ *
7743+ * @param string $selector Original CSS selector.
7744+ * @param string $to_append Selector to append.
7745+ * @param string $expected Expected resulting selector.
7746+ */
7747+ public function test_append_to_selector ( $ selector , $ to_append , $ expected ) {
7748+ $ theme_json = new ReflectionClass ( 'WP_Theme_JSON ' );
7749+
7750+ $ func = $ theme_json ->getMethod ( 'append_to_selector ' );
7751+ if ( PHP_VERSION_ID < 80100 ) {
7752+ $ func ->setAccessible ( true );
7753+ }
7754+
7755+ $ actual = $ func ->invoke ( null , $ selector , $ to_append );
7756+
7757+ $ this ->assertSame ( $ expected , $ actual );
7758+ }
7759+
7760+ /**
7761+ * Data provider.
7762+ *
7763+ * @return array<string, {selector: string, to_append: string, expeted: string}>
7764+ */
7765+ public function data_append_to_selector () {
7766+ return array (
7767+ 'single class selector ' => array (
7768+ 'selector ' => '.inner ' ,
7769+ 'to_append ' => ':hover ' ,
7770+ 'expected ' => '.inner:hover ' ,
7771+ ),
7772+ 'single element selector ' => array (
7773+ 'selector ' => 'p ' ,
7774+ 'to_append ' => ':hover ' ,
7775+ 'expected ' => 'p:hover ' ,
7776+ ),
7777+ 'single id selector ' => array (
7778+ 'selector ' => '#main ' ,
7779+ 'to_append ' => ':focus ' ,
7780+ 'expected ' => '#main:focus ' ,
7781+ ),
7782+ 'two comma-separated selectors without spaces ' => array (
7783+ 'selector ' => 'h1,h2 ' ,
7784+ 'to_append ' => ':hover ' ,
7785+ 'expected ' => 'h1:hover, h2:hover ' ,
7786+ ),
7787+ 'three comma-separated selectors without spaces ' => array (
7788+ 'selector ' => 'h1,h2,h3 ' ,
7789+ 'to_append ' => ':focus ' ,
7790+ 'expected ' => 'h1:focus, h2:focus, h3:focus ' ,
7791+ ),
7792+ 'comma-separated class selectors without spaces ' => array (
7793+ 'selector ' => '.foo,.bar ' ,
7794+ 'to_append ' => '.is-active ' ,
7795+ 'expected ' => '.foo.is-active, .bar.is-active ' ,
7796+ ),
7797+ 'append without leading pseudo ' => array (
7798+ 'selector ' => '.child ' ,
7799+ 'to_append ' => '.parent ' ,
7800+ 'expected ' => '.child.parent ' ,
7801+ ),
7802+ 'compound selector with class append no comma spaces ' => array (
7803+ 'selector ' => '.a,.b ' ,
7804+ 'to_append ' => '.parent ' ,
7805+ 'expected ' => '.a.parent, .b.parent ' ,
7806+ ),
7807+ 'descendant selector appended ' => array (
7808+ 'selector ' => '.block .inner ' ,
7809+ 'to_append ' => ':hover ' ,
7810+ 'expected ' => '.block .inner:hover ' ,
7811+ ),
7812+ 'descendant selectors comma-separated without spaces ' => array (
7813+ 'selector ' => '.block .inner,.block .alt ' ,
7814+ 'to_append ' => ':hover ' ,
7815+ 'expected ' => '.block .inner:hover, .block .alt:hover ' ,
7816+ ),
7817+ 'empty selector ' => array (
7818+ 'selector ' => '' ,
7819+ 'to_append ' => ':hover ' ,
7820+ 'expected ' => ':hover ' ,
7821+ ),
7822+ 'empty append ' => array (
7823+ 'selector ' => '.child ' ,
7824+ 'to_append ' => '' ,
7825+ 'expected ' => '.child ' ,
7826+ ),
7827+ 'both empty ' => array (
7828+ 'selector ' => '' ,
7829+ 'to_append ' => '' ,
7830+ 'expected ' => '' ,
7831+ ),
7832+ 'attribute selector ' => array (
7833+ 'selector ' => '[data-type="example"] ' ,
7834+ 'to_append ' => ':hover ' ,
7835+ 'expected ' => '[data-type="example"]:hover ' ,
7836+ ),
7837+ 'pseudo-class selector ' => array (
7838+ 'selector ' => ':where(.is-layout-flex) ' ,
7839+ 'to_append ' => ':hover ' ,
7840+ 'expected ' => ':where(.is-layout-flex):hover ' ,
7841+ ),
7842+ 'many comma-separated selectors without spaces ' => array (
7843+ 'selector ' => 'h1,h2,h3,h4,h5,h6 ' ,
7844+ 'to_append ' => ':hover ' ,
7845+ 'expected ' => 'h1:hover, h2:hover, h3:hover, h4:hover, h5:hover, h6:hover ' ,
7846+ ),
7847+ 'real world block element selector ' => array (
7848+ 'selector ' => 'p ' ,
7849+ 'to_append ' => '.is-style-custom ' ,
7850+ 'expected ' => 'p.is-style-custom ' ,
7851+ ),
7852+ 'real world compound block element selectors ' => array (
7853+ 'selector ' => 'a,.wp-element-button ' ,
7854+ 'to_append ' => '.is-style-custom ' ,
7855+ 'expected ' => 'a.is-style-custom, .wp-element-button.is-style-custom ' ,
7856+ ),
7857+ 'spaces after commas are normalized ' => array (
7858+ 'selector ' => 'h1, h2, h3 ' ,
7859+ 'to_append ' => ':hover ' ,
7860+ 'expected ' => 'h1:hover, h2:hover, h3:hover ' ,
7861+ ),
7862+ 'spaces after commas normalized with class selectors ' => array (
7863+ 'selector ' => '.foo, .bar ' ,
7864+ 'to_append ' => '.is-active ' ,
7865+ 'expected ' => '.foo.is-active, .bar.is-active ' ,
7866+ ),
7867+ 'mixed whitespace around commas is normalized ' => array (
7868+ 'selector ' => '.a , .b , .c ' ,
7869+ 'to_append ' => ':hover ' ,
7870+ 'expected ' => '.a:hover, .b:hover, .c:hover ' ,
7871+ ),
7872+ );
7873+ }
7874+
7875+ /**
7876+ * Tests that prepend_to_selector correctly prepends to single and
7877+ * compound (comma-separated) selectors.
7878+ *
7879+ * @ticket 65533
7880+ *
7881+ * @dataProvider data_prepend_to_selector
7882+ *
7883+ * @param string $selector Original CSS selector.
7884+ * @param string $to_prepend Selector to prepend.
7885+ * @param string $expected Expected resulting selector.
7886+ */
7887+ public function test_prepend_to_selector ( $ selector , $ to_prepend , $ expected ) {
7888+ $ theme_json = new ReflectionClass ( 'WP_Theme_JSON ' );
7889+
7890+ $ func = $ theme_json ->getMethod ( 'prepend_to_selector ' );
7891+ if ( PHP_VERSION_ID < 80100 ) {
7892+ $ func ->setAccessible ( true );
7893+ }
7894+
7895+ $ actual = $ func ->invoke ( null , $ selector , $ to_prepend );
7896+
7897+ $ this ->assertSame ( $ expected , $ actual );
7898+ }
7899+
7900+ /**
7901+ * Data provider.
7902+ *
7903+ * @return array<string, {selector: string, to_prepend: string, expeted: string}>
7904+ */
7905+ public function data_prepend_to_selector () {
7906+ return array (
7907+ 'single class selector ' => array (
7908+ 'selector ' => '.inner ' ,
7909+ 'to_prepend ' => '.wrapper ' ,
7910+ 'expected ' => '.wrapper .inner ' ,
7911+ ),
7912+ 'single element selector ' => array (
7913+ 'selector ' => 'p ' ,
7914+ 'to_prepend ' => '.wrapper ' ,
7915+ 'expected ' => '.wrapper p ' ,
7916+ ),
7917+ 'single id selector ' => array (
7918+ 'selector ' => '#main ' ,
7919+ 'to_prepend ' => '.wrapper ' ,
7920+ 'expected ' => '.wrapper #main ' ,
7921+ ),
7922+ 'two comma-separated selectors without spaces ' => array (
7923+ 'selector ' => 'h1,h2 ' ,
7924+ 'to_prepend ' => '.wrapper ' ,
7925+ 'expected ' => '.wrapper h1, .wrapper h2 ' ,
7926+ ),
7927+ 'three comma-separated selectors without spaces ' => array (
7928+ 'selector ' => 'h1,h2,h3 ' ,
7929+ 'to_prepend ' => '.some-class ' ,
7930+ 'expected ' => '.some-class h1, .some-class h2, .some-class h3 ' ,
7931+ ),
7932+ 'comma-separated class selectors without spaces ' => array (
7933+ 'selector ' => '.foo,.bar ' ,
7934+ 'to_prepend ' => '.prefix ' ,
7935+ 'expected ' => '.prefix .foo, .prefix .bar ' ,
7936+ ),
7937+ 'prepend without trailing space ' => array (
7938+ 'selector ' => '.child ' ,
7939+ 'to_prepend ' => '.parent ' ,
7940+ 'expected ' => '.parent.child ' ,
7941+ ),
7942+ 'compound selector without trailing space no comma spaces ' => array (
7943+ 'selector ' => '.a,.b ' ,
7944+ 'to_prepend ' => '.parent ' ,
7945+ 'expected ' => '.parent.a, .parent.b ' ,
7946+ ),
7947+ 'descendant selector prepended ' => array (
7948+ 'selector ' => '.block .inner ' ,
7949+ 'to_prepend ' => '.scope ' ,
7950+ 'expected ' => '.scope .block .inner ' ,
7951+ ),
7952+ 'descendant selectors comma-separated without spaces ' => array (
7953+ 'selector ' => '.block .inner,.block .alt ' ,
7954+ 'to_prepend ' => '.scope ' ,
7955+ 'expected ' => '.scope .block .inner, .scope .block .alt ' ,
7956+ ),
7957+ 'empty selector ' => array (
7958+ 'selector ' => '' ,
7959+ 'to_prepend ' => '.prefix ' ,
7960+ 'expected ' => '.prefix ' ,
7961+ ),
7962+ 'empty prepend ' => array (
7963+ 'selector ' => '.child ' ,
7964+ 'to_prepend ' => '' ,
7965+ 'expected ' => '.child ' ,
7966+ ),
7967+ 'both empty ' => array (
7968+ 'selector ' => '' ,
7969+ 'to_prepend ' => '' ,
7970+ 'expected ' => '' ,
7971+ ),
7972+ 'attribute selector ' => array (
7973+ 'selector ' => '[data-type="example"] ' ,
7974+ 'to_prepend ' => '.scope ' ,
7975+ 'expected ' => '.scope [data-type="example"] ' ,
7976+ ),
7977+ 'pseudo-class selector ' => array (
7978+ 'selector ' => ':where(.is-layout-flex) ' ,
7979+ 'to_prepend ' => '.editor ' ,
7980+ 'expected ' => '.editor :where(.is-layout-flex) ' ,
7981+ ),
7982+ 'many comma-separated selectors without spaces ' => array (
7983+ 'selector ' => 'h1,h2,h3,h4,h5,h6 ' ,
7984+ 'to_prepend ' => '.content ' ,
7985+ 'expected ' => '.content h1, .content h2, .content h3, .content h4, .content h5, .content h6 ' ,
7986+ ),
7987+ 'real world block element selector ' => array (
7988+ 'selector ' => 'p ' ,
7989+ 'to_prepend ' => '.wp-block-group ' ,
7990+ 'expected ' => '.wp-block-group p ' ,
7991+ ),
7992+ 'real world compound block element selectors ' => array (
7993+ 'selector ' => 'a,.wp-element-button ' ,
7994+ 'to_prepend ' => '.wp-block-group ' ,
7995+ 'expected ' => '.wp-block-group a, .wp-block-group .wp-element-button ' ,
7996+ ),
7997+ 'spaces after commas are normalized ' => array (
7998+ 'selector ' => 'h1, h2, h3 ' ,
7999+ 'to_prepend ' => '.some-class ' ,
8000+ 'expected ' => '.some-class h1, .some-class h2, .some-class h3 ' ,
8001+ ),
8002+ 'spaces after commas normalized with class selectors ' => array (
8003+ 'selector ' => '.foo, .bar ' ,
8004+ 'to_prepend ' => '.prefix ' ,
8005+ 'expected ' => '.prefix .foo, .prefix .bar ' ,
8006+ ),
8007+ 'mixed whitespace around commas are normalized ' => array (
8008+ 'selector ' => '.a , .b , .c ' ,
8009+ 'to_prepend ' => '.pre ' ,
8010+ 'expected ' => '.pre .a, .pre .b, .pre .c ' ,
8011+ ),
8012+ );
8013+ }
77348014}
0 commit comments