Skip to content

Commit a97a546

Browse files
authored
Merge pull request #165 from wp-cli/update-scaffolded-tests
Update scaffolded tests to latest.
2 parents c07b5d9 + 0c67fb7 commit a97a546

File tree

5 files changed

+131
-45
lines changed

5 files changed

+131
-45
lines changed

features/bootstrap/FeatureContext.php

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@
4545
class FeatureContext extends BehatContext implements ClosuredContextInterface {
4646

4747
/**
48-
* The current working directory for scenarios that have a "Given a WP install" or "Given an empty directory" step. Variable RUN_DIR. Lives until the end of the scenario.
48+
* The current working directory for scenarios that have a "Given a WP installation" or "Given an empty directory" step. Variable RUN_DIR. Lives until the end of the scenario.
4949
*/
5050
private static $run_dir;
5151

5252
/**
53-
* Where WordPress core is downloaded to for caching, and which is copied to RUN_DIR during a "Given a WP install" step. Lives until manually deleted.
53+
* Where WordPress core is downloaded to for caching, and which is copied to RUN_DIR during a "Given a WP installation" step. Lives until manually deleted.
5454
*/
5555
private static $cache_dir;
5656

5757
/**
58-
* The directory that holds the install cache, and which is copied to RUN_DIR during a "Given a WP install" step. Recreated on each suite run.
58+
* The directory that holds the install cache, and which is copied to RUN_DIR during a "Given a WP installation" step. Recreated on each suite run.
5959
*/
6060
private static $install_cache_dir;
6161

@@ -72,7 +72,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface {
7272
private static $composer_local_repository;
7373

7474
/**
75-
* The test database settings. All but `dbname` can be set via environment variables. The database is dropped at the start of each scenario and created on a "Given a WP install" step.
75+
* The test database settings. All but `dbname` can be set via environment variables. The database is dropped at the start of each scenario and created on a "Given a WP installation" step.
7676
*/
7777
private static $db_settings = array(
7878
'dbname' => 'wp_cli_test',
@@ -87,8 +87,9 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface {
8787
private $running_procs = array();
8888

8989
/**
90-
* Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest. Some are step-dependent:
91-
* RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
90+
* Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest.
91+
* Some are step-dependent: RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. One is set on use: INVOKE_WP_CLI_WITH_PHP_ARGS-args.
92+
* Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
9293
*/
9394
public $variables = array();
9495

@@ -117,8 +118,9 @@ private static function get_process_env_variables() {
117118
// Ensure we're using the expected `wp` binary
118119
$bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . '/../../bin' );
119120
$vendor_dir = realpath( __DIR__ . '/../../vendor/bin' );
121+
$path_separator = Utils\is_windows() ? ';' : ':';
120122
$env = array(
121-
'PATH' => $bin_dir . ':' . $vendor_dir . ':' . getenv( 'PATH' ),
123+
'PATH' => $bin_dir . $path_separator . $vendor_dir . $path_separator . getenv( 'PATH' ),
122124
'BEHAT_RUN' => 1,
123125
'HOME' => sys_get_temp_dir() . '/wp-cli-home',
124126
);
@@ -328,20 +330,57 @@ public function getHookDefinitionResources() {
328330
}
329331

330332
/**
331-
* Replace {VARIABLE_NAME}. Note that variable names can only contain uppercase letters and underscores (no numbers).
333+
* Replace standard {VARIABLE_NAME} variables and the special {INVOKE_WP_CLI_WITH_PHP_ARGS-args} and {WP_VERSION-version-latest} variables.
334+
* Note that standard variable names can only contain uppercase letters, digits and underscores and cannot begin with a digit.
332335
*/
333336
public function replace_variables( $str ) {
334-
$ret = preg_replace_callback( '/\{([A-Z_]+)\}/', array( $this, '_replace_var' ), $str );
337+
if ( false !== strpos( $str, '{INVOKE_WP_CLI_WITH_PHP_ARGS-' ) ) {
338+
$str = $this->replace_invoke_wp_cli_with_php_args( $str );
339+
}
340+
$str = preg_replace_callback( '/\{([A-Z_][A-Z_0-9]*)\}/', array( $this, 'replace_var' ), $str );
335341
if ( false !== strpos( $str, '{WP_VERSION-' ) ) {
336-
$ret = $this->_replace_wp_versions( $ret );
342+
$str = $this->replace_wp_versions( $str );
343+
}
344+
return $str;
345+
}
346+
347+
/**
348+
* Substitute {INVOKE_WP_CLI_WITH_PHP_ARGS-args} variables.
349+
*/
350+
private function replace_invoke_wp_cli_with_php_args( $str ) {
351+
static $phar_path = null, $shell_path = null;
352+
353+
if ( null === $phar_path ) {
354+
$phar_path = false;
355+
$phar_begin = '#!/usr/bin/env php';
356+
$phar_begin_len = strlen( $phar_begin );
357+
if ( ( $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ) && file_exists( $bin_dir . '/wp' ) && $phar_begin === file_get_contents( $bin_dir . '/wp', false, null, 0, $phar_begin_len ) ) {
358+
$phar_path = $bin_dir . '/wp';
359+
} else {
360+
$src_dir = dirname( dirname( __DIR__ ) );
361+
$bin_path = $src_dir . '/bin/wp';
362+
$vendor_bin_path = $src_dir . '/vendor/bin/wp';
363+
if ( file_exists( $bin_path ) && is_executable( $bin_path ) ) {
364+
$shell_path = $bin_path;
365+
} elseif ( file_exists( $vendor_bin_path ) && is_executable( $vendor_bin_path ) ) {
366+
$shell_path = $vendor_bin_path;
367+
} else {
368+
$shell_path = 'wp';
369+
}
370+
}
337371
}
338-
return $ret;
372+
373+
$str = preg_replace_callback( '/{INVOKE_WP_CLI_WITH_PHP_ARGS-([^}]*)}/', function ( $matches ) use ( $phar_path, $shell_path ) {
374+
return $phar_path ? "php {$matches[1]} {$phar_path}" : ( 'WP_CLI_PHP_ARGS=' . escapeshellarg( $matches[1] ) . ' ' . $shell_path );
375+
}, $str );
376+
377+
return $str;
339378
}
340379

341380
/**
342381
* Replace variables callback.
343382
*/
344-
private function _replace_var( $matches ) {
383+
private function replace_var( $matches ) {
345384
$cmd = $matches[0];
346385

347386
foreach ( array_slice( $matches, 1 ) as $key ) {
@@ -352,9 +391,9 @@ private function _replace_var( $matches ) {
352391
}
353392

354393
/**
355-
* Substitute "{WP_VERSION-version-latest}" variables.
394+
* Substitute {WP_VERSION-version-latest} variables.
356395
*/
357-
private function _replace_wp_versions( $str ) {
396+
private function replace_wp_versions( $str ) {
358397
static $wp_versions = null;
359398
if ( null === $wp_versions ) {
360399
$wp_versions = array();

features/bootstrap/Process.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace WP_CLI;
44

5+
use WP_CLI\Utils;
6+
57
/**
68
* Run a system process, and learn what happened.
79
*/
@@ -67,7 +69,7 @@ private function __construct() {}
6769
public function run() {
6870
$start_time = microtime( true );
6971

70-
$proc = proc_open( $this->command, self::$descriptors, $pipes, $this->cwd, $this->env );
72+
$proc = Utils\proc_open_compat( $this->command, self::$descriptors, $pipes, $this->cwd, $this->env );
7173

7274
$stdout = stream_get_contents( $pipes[1] );
7375
fclose( $pipes[1] );

features/bootstrap/utils.php

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -383,15 +383,11 @@ function launch_editor_for_input( $input, $filename = 'WP-CLI' ) {
383383

384384
$editor = getenv( 'EDITOR' );
385385
if ( ! $editor ) {
386-
$editor = 'vi';
387-
388-
if ( isset( $_SERVER['OS'] ) && false !== strpos( $_SERVER['OS'], 'indows' ) ) {
389-
$editor = 'notepad';
390-
}
386+
$editor = is_windows() ? 'notepad' : 'vi';
391387
}
392388

393389
$descriptorspec = array( STDIN, STDOUT, STDERR );
394-
$process = proc_open( "$editor " . escapeshellarg( $tmpfile ), $descriptorspec, $pipes );
390+
$process = proc_open_compat( "$editor " . escapeshellarg( $tmpfile ), $descriptorspec, $pipes );
395391
$r = proc_close( $process );
396392
if ( $r ) {
397393
exit( $r );
@@ -453,7 +449,7 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) {
453449

454450
$final_cmd = force_env_on_nix_systems( $cmd ) . assoc_args_to_str( $assoc_args );
455451

456-
$proc = proc_open( $final_cmd, $descriptors, $pipes );
452+
$proc = proc_open_compat( $final_cmd, $descriptors, $pipes );
457453
if ( ! $proc ) {
458454
exit( 1 );
459455
}
@@ -515,14 +511,15 @@ function mustache_render( $template_name, $data = array() ) {
515511
*
516512
* @param string $message Text to display before the progress bar.
517513
* @param integer $count Total number of ticks to be performed.
514+
* @param int $interval Optional. The interval in milliseconds between updates. Default 100.
518515
* @return cli\progress\Bar|WP_CLI\NoOp
519516
*/
520-
function make_progress_bar( $message, $count ) {
517+
function make_progress_bar( $message, $count, $interval = 100 ) {
521518
if ( \cli\Shell::isPiped() ) {
522519
return new \WP_CLI\NoOp;
523520
}
524521

525-
return new \cli\progress\Bar( $message, $count );
522+
return new \cli\progress\Bar( $message, $count, $interval );
526523
}
527524

528525
function parse_url( $url ) {
@@ -790,14 +787,8 @@ function get_temp_dir() {
790787
return $temp;
791788
}
792789

793-
$temp = '/tmp/';
794-
795-
// `sys_get_temp_dir()` introduced PHP 5.2.1.
796-
if ( $try = sys_get_temp_dir() ) {
797-
$temp = trailingslashit( $try );
798-
} elseif ( $try = ini_get( 'upload_tmp_dir' ) ) {
799-
$temp = trailingslashit( $try );
800-
}
790+
// `sys_get_temp_dir()` introduced PHP 5.2.1. Will always return something.
791+
$temp = trailingslashit( sys_get_temp_dir() );
801792

802793
if ( ! is_writable( $temp ) ) {
803794
\WP_CLI::warning( "Temp directory isn't writable: {$temp}" );
@@ -1129,7 +1120,7 @@ function get_suggestion( $target, array $options, $threshold = 2 ) {
11291120
'v' => 'version',
11301121
);
11311122

1132-
if ( array_key_exists( $target, $suggestion_map ) ) {
1123+
if ( array_key_exists( $target, $suggestion_map ) && in_array( $suggestion_map[ $target ], $options, true ) ) {
11331124
return $suggestion_map[ $target ];
11341125
}
11351126

@@ -1318,3 +1309,50 @@ function get_php_binary() {
13181309

13191310
return 'php';
13201311
}
1312+
1313+
/**
1314+
* Windows compatible `proc_open()`.
1315+
* Works around bug in PHP, and also deals with *nix-like `ENV_VAR=blah cmd` environment variable prefixes.
1316+
*
1317+
* @access public
1318+
*
1319+
* @param string $command Command to execute.
1320+
* @param array $descriptorspec Indexed array of descriptor numbers and their values.
1321+
* @param array &$pipes Indexed array of file pointers that correspond to PHP's end of any pipes that are created.
1322+
* @param string $cwd Initial working directory for the command.
1323+
* @param array $env Array of environment variables.
1324+
* @param array $other_options Array of additional options (Windows only).
1325+
*
1326+
* @return string Command stripped of any environment variable settings.
1327+
*/
1328+
function proc_open_compat( $cmd, $descriptorspec, &$pipes, $cwd = null, $env = null, $other_options = null ) {
1329+
if ( is_windows() ) {
1330+
// Need to encompass the whole command in double quotes - PHP bug https://bugs.php.net/bug.php?id=49139
1331+
$cmd = '"' . _proc_open_compat_win_env( $cmd, $env ) . '"';
1332+
}
1333+
return proc_open( $cmd, $descriptorspec, $pipes, $cwd, $env, $other_options );
1334+
}
1335+
1336+
/**
1337+
* For use by `proc_open_compat()` only. Separated out for ease of testing. Windows only.
1338+
* Turns *nix-like `ENV_VAR=blah command` environment variable prefixes into stripped `cmd` with prefixed environment variables added to passed in environment array.
1339+
*
1340+
* @access private
1341+
*
1342+
* @param string $command Command to execute.
1343+
* @param array &$env Array of existing environment variables. Will be modified if any settings in command.
1344+
*
1345+
* @return string Command stripped of any environment variable settings.
1346+
*/
1347+
function _proc_open_compat_win_env( $cmd, &$env ) {
1348+
if ( false !== strpos( $cmd, '=' ) ) {
1349+
while ( preg_match( '/^([A-Za-z_][A-Za-z0-9_]*)=("[^"]*"|[^ ]*) /', $cmd, $matches ) ) {
1350+
$cmd = substr( $cmd, strlen( $matches[0] ) );
1351+
if ( null === $env ) {
1352+
$env = array();
1353+
}
1354+
$env[ $matches[1] ] = isset( $matches[2][0] ) && '"' === $matches[2][0] ? substr( $matches[2], 1, -1 ) : $matches[2];
1355+
}
1356+
}
1357+
return $cmd;
1358+
}

features/steps/given.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,31 @@ function ( $world ) {
6969
}
7070
);
7171

72-
$steps->Given( '/^a WP install$/',
72+
$steps->Given( '/^a WP (install|installation)$/',
7373
function ( $world ) {
7474
$world->install_wp();
7575
}
7676
);
7777

78-
$steps->Given( "/^a WP install in '([^\s]+)'$/",
79-
function ( $world, $subdir ) {
78+
$steps->Given( "/^a WP (install|installation) in '([^\s]+)'$/",
79+
function ( $world, $_, $subdir ) {
8080
$world->install_wp( $subdir );
8181
}
8282
);
8383

84-
$steps->Given( '/^a WP install with Composer$/',
84+
$steps->Given( '/^a WP (install|installation) with Composer$/',
8585
function ( $world ) {
8686
$world->install_wp_with_composer();
8787
}
8888
);
8989

90-
$steps->Given( "/^a WP install with Composer and a custom vendor directory '([^\s]+)'$/",
91-
function ( $world, $vendor_directory ) {
90+
$steps->Given( "/^a WP (install|installation) with Composer and a custom vendor directory '([^\s]+)'$/",
91+
function ( $world, $_, $vendor_directory ) {
9292
$world->install_wp_with_composer( $vendor_directory );
9393
}
9494
);
9595

96-
$steps->Given( '/^a WP multisite (subdirectory|subdomain)?\s?install$/',
96+
$steps->Given( '/^a WP multisite (subdirectory|subdomain)?\s?(install|installation)$/',
9797
function ( $world, $type = 'subdirectory' ) {
9898
$world->install_wp();
9999
$subdomains = ! empty( $type ) && 'subdomain' === $type ? 1 : 0;

utils/behat-tags.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,24 @@ function version_tags( $prefix, $current, $operator = '<' ) {
3131
return $skip_tags;
3232
}
3333

34+
$wp_version = getenv( 'WP_VERSION' );
3435
$wp_version_reqs = array();
35-
// Only apply @require-wp tags when WP_VERSION isn't 'latest' or 'nightly'
36-
// 'latest' and 'nightly' are expected to work with all features
37-
if ( ! in_array( getenv( 'WP_VERSION' ), array( 'latest', 'nightly', 'trunk' ), true ) ) {
38-
$wp_version_reqs = version_tags( 'require-wp', getenv( 'WP_VERSION' ), '<' );
36+
// Only apply @require-wp tags when WP_VERSION isn't 'latest', 'nightly' or 'trunk'.
37+
// 'latest', 'nightly' and 'trunk' are expected to work with all features.
38+
if ( $wp_version && ! in_array( $wp_version, array( 'latest', 'nightly', 'trunk' ), true ) ) {
39+
$wp_version_reqs = array_merge(
40+
version_tags( 'require-wp', $wp_version, '<' ),
41+
version_tags( 'less-than-wp', $wp_version, '>=' )
42+
);
43+
} else {
44+
// But make sure @less-than-wp tags always exist for those special cases. (Note: @less-than-wp-latest etc won't work and shouldn't be used).
45+
$wp_version_reqs = array_merge( $wp_version_reqs, version_tags( 'less-than-wp', '9999', '>=' ) );
3946
}
4047

4148
$skip_tags = array_merge(
4249
$wp_version_reqs,
4350
version_tags( 'require-php', PHP_VERSION, '<' ),
44-
version_tags( 'less-than-php', PHP_VERSION, '>' )
51+
version_tags( 'less-than-php', PHP_VERSION, '>=' ) // Note: this was '>' prior to WP-CLI 1.5.0 but the change is unlikely to cause BC issues as usually compared against major.minor only.
4552
);
4653

4754
# Skip Github API tests if `GITHUB_TOKEN` not available because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612

0 commit comments

Comments
 (0)