shortcodes as $shortcode ) { add_shortcode( $shortcode, array( $this, '_shortcode_' . str_replace( '-', '_', $shortcode ) ) ); } $this->atts = null; $this->content = null; $this->tagname = null; } function tearDown() { global $shortcode_tags; foreach ( $this->shortcodes as $shortcode ) { unset( $shortcode_tags[ $shortcode ] ); } parent::tearDown(); } function _shortcode_test_shortcode_tag( $atts, $content = null, $tagname = null ) { $this->atts = $atts; $this->content = $content; $this->tagname = $tagname; $this->filter_atts_out = null; $this->filter_atts_pairs = null; $this->filter_atts_atts = null; } // [footag foo="bar"] function _shortcode_footag( $atts ) { $foo = isset( $atts['foo'] ) ? $atts['foo'] : ''; return "foo = $foo"; } // [bartag foo="bar"] function _shortcode_bartag( $atts ) { $processed_atts = shortcode_atts( array( 'foo' => 'no foo', 'baz' => 'default baz', ), $atts, 'bartag' ); return "foo = {$processed_atts['foo']}"; } // [baztag]content[/baztag] function _shortcode_baztag( $atts, $content = '' ) { return 'content = ' . do_shortcode( $content ); } function _shortcode_dumptag( $atts ) { $out = ''; foreach ( $atts as $k => $v ) { $out .= "$k = $v\n"; } return $out; } function _shortcode_hyphen() { return __FUNCTION__; } function _shortcode_hyphen_foo() { return __FUNCTION__; } function _shortcode_hyphen_foo_bar() { return __FUNCTION__; } function _shortcode_url() { return 'http://www.wordpress.org/'; } function _shortcode_img( $atts ) { $out = ' $v ) { $out .= " $k=\"$v\""; } $out .= ' />'; return $out; } function test_noatts() { do_shortcode( '[test-shortcode-tag /]' ); $this->assertSame( '', $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_one_att() { do_shortcode( '[test-shortcode-tag foo="asdf" /]' ); $this->assertSame( array( 'foo' => 'asdf' ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_not_a_tag() { $out = do_shortcode( '[not-a-shortcode-tag]' ); $this->assertSame( '[not-a-shortcode-tag]', $out ); } /** * @ticket 17657 */ function test_tag_hyphen_not_tag() { $out = do_shortcode( '[dumptag-notreal]' ); $this->assertSame( '[dumptag-notreal]', $out ); } function test_tag_underscore_not_tag() { $out = do_shortcode( '[dumptag_notreal]' ); $this->assertSame( '[dumptag_notreal]', $out ); } function test_tag_not_tag() { $out = do_shortcode( '[dumptagnotreal]' ); $this->assertSame( '[dumptagnotreal]', $out ); } /** * @ticket 17657 */ function test_tag_hyphen() { $this->assertSame( '_shortcode_hyphen', do_shortcode( '[hyphen]' ) ); $this->assertSame( '_shortcode_hyphen_foo', do_shortcode( '[hyphen-foo]' ) ); $this->assertSame( '_shortcode_hyphen_foo_bar', do_shortcode( '[hyphen-foo-bar]' ) ); $this->assertSame( '[hyphen-baz]', do_shortcode( '[hyphen-baz]' ) ); $this->assertSame( '[hyphen-foo-bar-baz]', do_shortcode( '[hyphen-foo-bar-baz]' ) ); } /** * @ticket 9405 */ function test_attr_hyphen() { do_shortcode( '[test-shortcode-tag foo="foo" foo-bar="foo-bar" foo-bar-="foo-bar-" -foo-bar="-foo-bar" -foo-bar-="-foo-bar-" foo-bar-baz="foo-bar-baz" -foo-bar-baz="-foo-bar-baz" foo--bar="foo--bar" /]' ); $expected_attrs = array( 'foo' => 'foo', 'foo-bar' => 'foo-bar', 'foo-bar-' => 'foo-bar-', '-foo-bar' => '-foo-bar', '-foo-bar-' => '-foo-bar-', 'foo-bar-baz' => 'foo-bar-baz', '-foo-bar-baz' => '-foo-bar-baz', 'foo--bar' => 'foo--bar', ); $this->assertSame( $expected_attrs, $this->atts ); } function test_two_atts() { do_shortcode( '[test-shortcode-tag foo="asdf" bar="bing" /]' ); $this->assertSame( array( 'foo' => 'asdf', 'bar' => 'bing', ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_noatts_enclosing() { do_shortcode( '[test-shortcode-tag]content[/test-shortcode-tag]' ); $this->assertSame( '', $this->atts ); $this->assertSame( 'content', $this->content ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_one_att_enclosing() { do_shortcode( '[test-shortcode-tag foo="bar"]content[/test-shortcode-tag]' ); $this->assertSame( array( 'foo' => 'bar' ), $this->atts ); $this->assertSame( 'content', $this->content ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_two_atts_enclosing() { do_shortcode( '[test-shortcode-tag foo="bar" baz="bing"]content[/test-shortcode-tag]' ); $this->assertSame( array( 'foo' => 'bar', 'baz' => 'bing', ), $this->atts ); $this->assertSame( 'content', $this->content ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_unclosed() { $out = do_shortcode( '[test-shortcode-tag]' ); $this->assertSame( '', $out ); $this->assertSame( '', $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_positional_atts_num() { $out = do_shortcode( '[test-shortcode-tag 123]' ); $this->assertSame( '', $out ); $this->assertSame( array( 0 => '123' ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_positional_atts_url() { $out = do_shortcode( '[test-shortcode-tag https://www.youtube.com/watch?v=72xdCU__XCk]' ); $this->assertSame( '', $out ); $this->assertSame( array( 0 => 'https://www.youtube.com/watch?v=72xdCU__XCk' ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_positional_atts_quotes() { $out = do_shortcode( '[test-shortcode-tag "something in quotes" "something else"]' ); $this->assertSame( '', $out ); $this->assertSame( array( 0 => 'something in quotes', 1 => 'something else', ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_positional_atts_mixed() { $out = do_shortcode( '[test-shortcode-tag 123 https://wordpress.org/ 0 "foo" bar]' ); $this->assertSame( '', $out ); $this->assertSame( array( 0 => '123', 1 => 'https://wordpress.org/', 2 => '0', 3 => 'foo', 4 => 'bar', ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_positional_and_named_atts() { $out = do_shortcode( '[test-shortcode-tag 123 url=https://wordpress.org/ foo bar="baz"]' ); $this->assertSame( '', $out ); $this->assertSame( array( 0 => '123', 'url' => 'https://wordpress.org/', 1 => 'foo', 'bar' => 'baz', ), $this->atts ); $this->assertSame( 'test-shortcode-tag', $this->tagname ); } function test_footag_default() { $out = do_shortcode( '[footag]' ); $this->assertSame( 'foo = ', $out ); } function test_footag_val() { $val = rand_str(); $out = do_shortcode( '[footag foo="' . $val . '"]' ); $this->assertSame( 'foo = ' . $val, $out ); } function test_nested_tags() { $out = do_shortcode( '[baztag][dumptag abc="foo" def=123 https://wordpress.org/][/baztag]' ); $expected = "content = abc = foo\ndef = 123\n0 = https://wordpress.org\n"; $this->assertSame( $expected, $out ); } /** * @ticket 6518 */ function test_tag_escaped() { $out = do_shortcode( '[[footag]] [[bartag foo="bar"]]' ); $this->assertSame( '[footag] [bartag foo="bar"]', $out ); $out = do_shortcode( '[[footag /]] [[bartag foo="bar" /]]' ); $this->assertSame( '[footag /] [bartag foo="bar" /]', $out ); $out = do_shortcode( '[[baztag foo="bar"]the content[/baztag]]' ); $this->assertSame( '[baztag foo="bar"]the content[/baztag]', $out ); // Double escaped. $out = do_shortcode( '[[[footag]]] [[[bartag foo="bar"]]]' ); $this->assertSame( '[[footag]] [[bartag foo="bar"]]', $out ); } function test_tag_not_escaped() { // These have square brackets on either end but aren't actually escaped. $out = do_shortcode( '[[footag] [bartag foo="bar"]]' ); $this->assertSame( '[foo = foo = bar]', $out ); $out = do_shortcode( '[[footag /] [bartag foo="bar" /]]' ); $this->assertSame( '[foo = foo = bar]', $out ); $out = do_shortcode( '[[baztag foo="bar"]the content[/baztag]' ); $this->assertSame( '[content = the content', $out ); $out = do_shortcode( '[[not-a-tag]]' ); $this->assertSame( '[[not-a-tag]]', $out ); $out = do_shortcode( '[[[footag] [bartag foo="bar"]]]' ); $this->assertSame( '[[foo = foo = bar]]', $out ); } function test_mixed_tags() { $in = <<assertSame( strip_ws( $expected ), strip_ws( $out ) ); } /** * @ticket 6562 */ function test_utf8_whitespace_1() { // NO-BREAK SPACE: U+00A0. do_shortcode( "[test-shortcode-tag foo=\"bar\" \xC2\xA0baz=\"123\"]" ); $this->assertSame( array( 'foo' => 'bar', 'baz' => '123', ), $this->atts ); $this->assertSame( '', $this->content ); } /** * @ticket 6562 */ function test_utf8_whitespace_2() { // ZERO WIDTH SPACE: U+200B. do_shortcode( "[test-shortcode-tag foo=\"bar\" \xE2\x80\x8Babc=\"def\"]" ); $this->assertSame( array( 'foo' => 'bar', 'abc' => 'def', ), $this->atts ); $this->assertSame( '', $this->content ); } /** * @ticket 14050 */ function test_shortcode_unautop() { // A blank line is added at the end, so test with it already there. $test_string = "[footag]\n"; $this->assertSame( $test_string, shortcode_unautop( wpautop( $test_string ) ) ); } function data_test_strip_shortcodes() { return array( array( 'before', 'before[gallery]' ), array( 'after', '[gallery]after' ), array( 'beforeafter', 'before[gallery]after' ), array( 'before[after', 'before[after' ), array( 'beforeafter', 'beforeafter' ), array( 'beforeafter', 'before[gallery id="123" size="medium"]after' ), array( 'before[unregistered_shortcode]after', 'before[unregistered_shortcode]after' ), array( 'beforeafter', 'before[footag]after' ), array( 'before after', 'before [footag]content[/footag] after' ), array( 'before after', 'before [footag foo="123"]content[/footag] after' ), ); } /** * @ticket 10326 * * @dataProvider data_test_strip_shortcodes * * @param string $expected Expected output. * @param string $content Content to run strip_shortcodes() on. */ function test_strip_shortcodes( $expected, $content ) { $this->assertSame( $expected, strip_shortcodes( $content ) ); } /** * @ticket 37767 */ function test_strip_shortcodes_filter() { add_filter( 'strip_shortcodes_tagnames', array( $this, '_filter_strip_shortcodes_tagnames' ) ); $this->assertSame( 'beforemiddle [footag]after', strip_shortcodes( 'before[gallery]middle [footag]after' ) ); remove_filter( 'strip_shortcodes_tagnames', array( $this, '_filter_strip_shortcodes_tagnames' ) ); } function _filter_strip_shortcodes_tagnames() { return array( 'gallery' ); } // Store passed in shortcode_atts_{$shortcode} args. function _filter_atts( $out, $pairs, $atts ) { $this->filter_atts_out = $out; $this->filter_atts_pairs = $pairs; $this->filter_atts_atts = $atts; return $out; } // Filter shortcode atts in various ways. function _filter_atts2( $out, $pairs, $atts ) { // If foo attribute equals "foo1", change it to be default value. if ( isset( $out['foo'] ) && 'foo1' === $out['foo'] ) { $out['foo'] = $pairs['foo']; } // If baz attribute is set, remove it. if ( isset( $out['baz'] ) ) { unset( $out['baz'] ); } $this->filter_atts_out = $out; return $out; } function test_shortcode_atts_filter_passes_original_arguments() { add_filter( 'shortcode_atts_bartag', array( $this, '_filter_atts' ), 10, 3 ); do_shortcode( '[bartag foo="foo1" /]' ); $this->assertSame( array( 'foo' => 'foo1', 'baz' => 'default baz', ), $this->filter_atts_out ); $this->assertSame( array( 'foo' => 'no foo', 'baz' => 'default baz', ), $this->filter_atts_pairs ); $this->assertSame( array( 'foo' => 'foo1' ), $this->filter_atts_atts ); remove_filter( 'shortcode_atts_bartag', array( $this, '_filter_atts' ), 10, 3 ); } function test_shortcode_atts_filtering() { add_filter( 'shortcode_atts_bartag', array( $this, '_filter_atts2' ), 10, 3 ); $out = do_shortcode( '[bartag foo="foo1" baz="baz1" /]' ); $this->assertSame( array( 'foo' => 'no foo' ), $this->filter_atts_out ); $this->assertSame( 'foo = no foo', $out ); $out = do_shortcode( '[bartag foo="foo2" /]' ); $this->assertSame( 'foo = foo2', $out ); remove_filter( 'shortcode_atts_bartag', array( $this, '_filter_atts2' ), 10, 3 ); } /** * Check that shortcode_unautop() will always recognize spaces around shortcodes. * * @ticket 22692 */ function test_spaces_around_shortcodes() { $nbsp = "\xC2\xA0"; $input = array(); $input[] = '

[gallery ids="37,15,11"]

'; $input[] = '

[gallery ids="37,15,11"]

'; $input[] = "

{$nbsp}[gallery ids=\"37,15,11\"] {$nbsp}

"; $input[] = '

 [gallery ids="37,15,11"]  

'; $output = '[gallery ids="37,15,11"]'; foreach ( $input as $in ) { $this->assertSame( $output, shortcode_unautop( $in ) ); } } /** * Check for bugginess using normal input with latest patches. * * @dataProvider data_escaping */ function test_escaping( $input, $output ) { return $this->assertSame( $output, do_shortcode( $input ) ); } function data_escaping() { return array( array( '