From 3ed7288ed8fecf5229582fd21508ee58b0b5dd55 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 14 Aug 2026 09:28:46 +0400 Subject: [PATCH] Automatically bootstrap interactive PHP snippets --- lib/runner.php | 29 +++++++- tests/phpunit/tests/export/docblocks.inc | 12 ---- tests/phpunit/tests/export/docblocks.php | 67 +++++++++++++------ .../tests/export/fence-first-docblocks.inc | 4 -- 4 files changed, 73 insertions(+), 39 deletions(-) diff --git a/lib/runner.php b/lib/runner.php index 70e77d9..58cbabe 100644 --- a/lib/runner.php +++ b/lib/runner.php @@ -994,7 +994,7 @@ function export_docblock_code_snippets( $text, &$setup_blueprints = null, $fence $snippet = array( 'type' => 'php-code-snippet', - 'code' => $fences[ $i ]['code'], + 'code' => add_docblock_php_snippet_preamble( $fences[ $i ]['code'] ), ); if ( null !== $fences[ $i ]['referenced_setup'] ) { @@ -1085,6 +1085,33 @@ function export_docblock_code_snippets( $text, &$setup_blueprints = null, $fence return $snippets; } +/** + * Adds the WordPress bootstrap preamble to an interactive PHP snippet. + * + * Interactive snippets run in a standalone PHP process, so they need to load + * WordPress before executing the example. Authors may omit the boilerplate from + * the fenced code. Existing snippets that include the PHP opening tag or the + * complete preamble are normalized without duplicating either line. + * + * @param string $code Snippet code extracted from a DocBlock fence. + * + * @return string Complete runnable PHP code. + */ +function add_docblock_php_snippet_preamble( $code ) { + $preamble = " 'php-code-snippet', - 'code' => " " 'php-code-snippet', - 'code' => " " 'shared', ), ), @@ -142,7 +142,7 @@ public function test_fence_first_docblocks() { ); $this->assertSame( - "assertSame( @@ -154,7 +154,7 @@ public function test_fence_first_docblocks() { array( array( 'type' => 'php-code-snippet', - 'code' => " " array( "````php interactive\n array( "```php interactive\n array( " ```php interactive\n array( " ```php interactive\n 'php-code-snippet', - 'code' => " "assertSame( + $preamble . "\necho 'body only';", + \WP_Parser\export_docblock_code_snippets( + "```php interactive\necho 'body only';\n```" + )[0]['code'] + ); + $this->assertSame( + $preamble . "\necho 'opening tag';", + \WP_Parser\export_docblock_code_snippets( + "```php interactive\nassertSame( + $preamble . "\necho 'complete preamble';", + \WP_Parser\export_docblock_code_snippets( + "```php interactive\n" . $preamble . "\necho 'complete preamble';\n```" + )[0]['code'] + ); + } + /** * Test that unsupported info strings remain ordinary documentation. * @@ -608,11 +634,11 @@ public function test_code_snippet_inline_placeholders() { array( array( 'type' => 'php-code-snippet', - 'code' => " " 'php-code-snippet', - 'code' => " " 'done', ), ), @@ -779,7 +805,7 @@ public function test_code_snippet_metadata_rejects_extra_arguments() { array( array( 'type' => 'php-code-snippet', - 'code' => " " 'php-code-snippet', - 'code' => " " 'First', ), array( 'type' => 'php-code-snippet', - 'code' => " " array( 'steps' => array( array( @@ -1088,7 +1113,6 @@ public function test_code_snippet_metadata_boundaries() { "\n", array( '```php interactive', - ' 'php-code-snippet', - 'code' => " " 'first', 'blueprint' => 'shared', ), array( 'type' => 'php-code-snippet', - 'code' => " " 'no leaked inline blueprint', ), array( 'type' => 'php-code-snippet', - 'code' => " " 'shared', ), ), @@ -1221,7 +1244,7 @@ public function test_property_docblocks() { 'code_snippets' => array( array( 'type' => 'php-code-snippet', - 'code' => " " 'Hello from the file setup', 'blueprint' => 'file-greeting', ), diff --git a/tests/phpunit/tests/export/fence-first-docblocks.inc b/tests/phpunit/tests/export/fence-first-docblocks.inc index 39a7249..77b1785 100644 --- a/tests/phpunit/tests/export/fence-first-docblocks.inc +++ b/tests/phpunit/tests/export/fence-first-docblocks.inc @@ -6,7 +6,6 @@ * ``` * * ```php interactive setup-blueprint=shared - *