diff --git a/features/behat-steps.feature b/features/behat-steps.feature index b38eac4c..beaeaf5c 100644 --- a/features/behat-steps.feature +++ b/features/behat-steps.feature @@ -389,6 +389,19 @@ Feature: Test that WP-CLI Behat steps work as expected """ Then the wp-cli.yml file should exist And the mock-requests.php file should exist + And the mock-requests-data.php file should exist + + When I run `php -l mock-requests.php` + Then STDOUT should contain: + """ + No syntax errors detected + """ + + When I run `php -l mock-requests-data.php` + Then STDOUT should contain: + """ + No syntax errors detected + """ @require-wp Scenario: Test background process launch diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 0aff9e2d..cad05419 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -98,4 +98,19 @@ */generate-coverage\.php$ + + + + */src/Context/templates/* + + + */src/Context/templates/* + + + */src/Context/templates/* + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 427c1a52..50a31b50 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,6 +7,9 @@ parameters: - tests excludePaths: - tests/data + # Templates are copied into the test run directory and executed by the + # child WP-CLI process, where Requests v1 classes may still exist. + - src/Context/templates scanDirectories: - vendor/wp-cli/wp-cli - vendor/phpunit/php-code-coverage diff --git a/src/Context/GivenStepDefinitions.php b/src/Context/GivenStepDefinitions.php index baf92cf9..03a87493 100644 --- a/src/Context/GivenStepDefinitions.php +++ b/src/Context/GivenStepDefinitions.php @@ -191,6 +191,7 @@ public function given_a_request_to_a_url_respond_with_file( $url_or_pattern, PyS $config_file = $this->variables['RUN_DIR'] . '/wp-cli.yml'; $mock_file = $this->variables['RUN_DIR'] . '/mock-requests.php'; + $data_file = $this->variables['RUN_DIR'] . '/mock-requests-data.php'; $dir = dirname( $config_file ); if ( ! file_exists( $dir ) ) { @@ -209,146 +210,12 @@ public function given_a_request_to_a_url_respond_with_file( $url_or_pattern, PyS $this->mocked_requests[ $url_or_pattern ] = (string) $content; - $mocked_requests = var_export( $this->mocked_requests, true /* return */ ); - - $mock_file_contents = << \$response ) { - \$pattern = '/' . preg_quote( \$pattern, '/' ) . '/'; - if ( 1 === preg_match( \$pattern, \$url ) ) { - \$pos = strpos( \$response, "\\n\\n"); - if ( false !== \$pos ) { - \$response = substr( \$response, 0, \$pos ) . "\\r\\n\\r\\n" . substr( \$response, \$pos + 2 ); - } - if ( ! empty( \$options['filename'] ) ) { - \$body = ''; - \$body_pos = strpos( \$response, "\\r\\n\\r\\n" ); - if ( false !== \$body_pos ) { - \$body = substr( \$response, \$body_pos + 4 ); - } - file_put_contents( \$options['filename'], \$body ); - } - return \$response; - } - } - - if ( class_exists( '\WpOrg\Requests\Transport\Curl' ) ) { - return ( new \WpOrg\Requests\Transport\Curl() )->request( \$url, \$headers, \$data, \$options ); - } - - return ( new \Requests_Transport_cURL() )->request( \$url, \$headers, \$data, \$options ); - } - - public function request_multiple( \$requests, \$options ) { - throw new Exception( 'Method not implemented: ' . __METHOD__ ); - } - - public static function test( \$capabilities = array() ) { - return true; - } -} - -if ( interface_exists( '\WpOrg\Requests\Transport' ) ) { - class WP_CLI_Tests_Mock_Requests_Transport implements \WpOrg\Requests\Transport { - use WP_CLI_Tests_Mock_Requests_Trait; - } -} else { - class WP_CLI_Tests_Mock_Requests_Transport implements \Requests_Transport { - use WP_CLI_Tests_Mock_Requests_Trait; - } -} - -WP_CLI::add_hook( - 'http_request_options', - static function( \$options ) { - \$options['transport'] = new WP_CLI_Tests_Mock_Requests_Transport(); - return \$options; - } -); - -WP_CLI::add_wp_hook( - 'pre_http_request', - static function( \$pre, \$parsed_args, \$url ) { - \$mocked_requests = $mocked_requests; - - foreach ( \$mocked_requests as \$pattern => \$response ) { - \$pattern = '/' . preg_quote( \$pattern, '/' ) . '/'; - if ( 1 === preg_match( \$pattern, \$url ) ) { - \$pos = strpos( \$response, "\n\n"); - if ( false !== \$pos ) { - \$response = substr( \$response, 0, \$pos ) . "\r\n\r\n" . substr( \$response, \$pos + 2 ); - } - - if ( class_exists( '\WpOrg\Requests\Requests' ) ) { - WpOrg\Requests\Requests::parse_multiple( - \$response, - array( - 'url' => \$url, - 'headers' => array(), - 'data' => array(), - 'options' => array_merge( - WpOrg\Requests\Requests::OPTION_DEFAULTS, - array( - 'hooks' => new WpOrg\Requests\Hooks(), - ) - ), - ) - ); - } else { - \Requests::parse_multiple( - \$response, - array( - 'url' => \$url, - 'headers' => array(), - 'data' => array(), - 'options' => array( - 'blocking' => true, - 'filename' => false, - 'follow_redirects' => true, - 'redirected' => 0, - 'redirects' => 10, - 'hooks' => new Requests_Hooks(), - ), - ) - ); - } - - if ( ! empty( \$parsed_args['filename'] ) ) { - file_put_contents( \$parsed_args['filename'], \$response->body ); - } - - return array( - 'headers' => \$response->headers->getAll(), - 'body' => \$response->body, - 'response' => array( - 'code' => \$response->status_code, - 'message' => get_status_header_desc( \$response->status_code ), - ), - 'cookies' => array(), - 'filename' => '', - ); - } - } - - return \$pre; - }, - 10, - 3 -); -FILE; - file_put_contents( - $mock_file, - $mock_file_contents + $data_file, + 'mocked_requests, true /* return */ ) . ';' . PHP_EOL ); + + copy( __DIR__ . '/templates/mock-requests.php', $mock_file ); } /** diff --git a/src/Context/templates/mock-requests.php b/src/Context/templates/mock-requests.php new file mode 100644 index 00000000..db3afe07 --- /dev/null +++ b/src/Context/templates/mock-requests.php @@ -0,0 +1,135 @@ + $response ) { + $pattern = '/' . preg_quote( $pattern, '/' ) . '/'; + if ( 1 === preg_match( $pattern, $url ) ) { + $pos = strpos( $response, "\n\n" ); + if ( false !== $pos ) { + $response = substr( $response, 0, $pos ) . "\r\n\r\n" . substr( $response, $pos + 2 ); + } + if ( ! empty( $options['filename'] ) ) { + $body = ''; + $body_pos = strpos( $response, "\r\n\r\n" ); + if ( false !== $body_pos ) { + $body = substr( $response, $body_pos + 4 ); + } + file_put_contents( $options['filename'], $body ); + } + return $response; + } + } + + if ( class_exists( '\WpOrg\Requests\Transport\Curl' ) ) { + return ( new \WpOrg\Requests\Transport\Curl() )->request( $url, $headers, $data, $options ); + } + + return ( new \Requests_Transport_cURL() )->request( $url, $headers, $data, $options ); + } + + public function request_multiple( $requests, $options ) { + throw new Exception( 'Method not implemented: ' . __METHOD__ ); + } + + public static function test( $capabilities = array() ) { + return true; + } +} + +if ( interface_exists( '\WpOrg\Requests\Transport' ) ) { + class WP_CLI_Tests_Mock_Requests_Transport implements \WpOrg\Requests\Transport { + use WP_CLI_Tests_Mock_Requests_Trait; + } +} else { + class WP_CLI_Tests_Mock_Requests_Transport implements \Requests_Transport { + use WP_CLI_Tests_Mock_Requests_Trait; + } +} + +WP_CLI::add_hook( + 'http_request_options', + static function ( $options ) { + $options['transport'] = new WP_CLI_Tests_Mock_Requests_Transport(); + return $options; + } +); + +WP_CLI::add_wp_hook( + 'pre_http_request', + static function ( $pre, $parsed_args, $url ) { + $mocked_requests = require __DIR__ . '/mock-requests-data.php'; + + foreach ( $mocked_requests as $pattern => $response ) { + $pattern = '/' . preg_quote( $pattern, '/' ) . '/'; + if ( 1 === preg_match( $pattern, $url ) ) { + $pos = strpos( $response, "\n\n" ); + if ( false !== $pos ) { + $response = substr( $response, 0, $pos ) . "\r\n\r\n" . substr( $response, $pos + 2 ); + } + + if ( class_exists( '\WpOrg\Requests\Requests' ) ) { + WpOrg\Requests\Requests::parse_multiple( + $response, + array( + 'url' => $url, + 'headers' => array(), + 'data' => array(), + 'options' => array_merge( + WpOrg\Requests\Requests::OPTION_DEFAULTS, + array( + 'hooks' => new WpOrg\Requests\Hooks(), + ) + ), + ) + ); + } else { + \Requests::parse_multiple( + $response, + array( + 'url' => $url, + 'headers' => array(), + 'data' => array(), + 'options' => array( + 'blocking' => true, + 'filename' => false, + 'follow_redirects' => true, + 'redirected' => 0, + 'redirects' => 10, + 'hooks' => new Requests_Hooks(), + ), + ) + ); + } + + if ( ! empty( $parsed_args['filename'] ) ) { + file_put_contents( $parsed_args['filename'], $response->body ); + } + + return array( + 'headers' => $response->headers->getAll(), + 'body' => $response->body, + 'response' => array( + 'code' => $response->status_code, + 'message' => get_status_header_desc( $response->status_code ), + ), + 'cookies' => array(), + 'filename' => '', + ); + } + } + + return $pre; + }, + 10, + 3 +);