Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions src/Context/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
use Behat\Testwork\Hook\Scope\BeforeSuiteScope;
use Behat\Behat\Hook\Scope\AfterFeatureScope;
use Behat\Behat\Hook\Scope\BeforeFeatureScope;
use Behat\Behat\Hook\Scope\BeforeStepScope;
use SebastianBergmann\CodeCoverage\Report\Clover;
use SebastianBergmann\CodeCoverage\Driver\Selector;
use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\Environment\Runtime;
use RuntimeException;
use DirectoryIterator;
use WP_CLI\Process;
use WP_CLI\Utils;
use WP_CLI\WpOrgApi;
Expand Down Expand Up @@ -131,6 +138,13 @@
*/
private $scenario;

/**
* Line of the current step.
*
* @var int
*/
private $step_line = 0;

/**
* @BeforeFeature
*/
Expand All @@ -145,11 +159,19 @@
$this->scenario = $scope->getScenario();
}

/**
* @BeforeStep
*/
public function store_step( BeforeStepScope $scope ) {
$this->step_line = $scope->getStep()->getLine();

Check warning on line 166 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L165-L166

Added lines #L165 - L166 were not covered by tests
}

/**
* @AfterScenario
*/
public function forget_scenario( AfterScenarioScope $scope ) {
$this->scenario = null;
$this->step_line = 0;
$this->scenario = null;

Check warning on line 174 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L173-L174

Added lines #L173 - L174 were not covered by tests
}

/**
Expand All @@ -159,6 +181,34 @@
self::$feature = null;
}

/**
* @AfterSuite
*/
public static function merge_coverage_reports() {
$with_code_coverage = (string) getenv( 'WP_CLI_TEST_COVERAGE' );

Check warning on line 188 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L187-L188

Added lines #L187 - L188 were not covered by tests

if ( ! \in_array( $with_code_coverage, [ 'true', '1' ], true ) ) {
return;

Check warning on line 191 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L190-L191

Added lines #L190 - L191 were not covered by tests
}

$filter = new Filter();
$coverage = new CodeCoverage(
( new Selector() )->forLineCoverage( $filter ),
$filter
);

Check warning on line 198 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L194-L198

Added lines #L194 - L198 were not covered by tests

foreach ( new DirectoryIterator( self::$behat_run_dir . '/build/logs' ) as $file ) {
if ( ! $file->isFile() || 'cov' !== $file->getExtension() ) {
continue;

Check warning on line 202 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L200-L202

Added lines #L200 - L202 were not covered by tests
}

$coverage->merge( include $file->getPathname() );
unlink( $file->getPathname() );

Check warning on line 206 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L205-L206

Added lines #L205 - L206 were not covered by tests
}

( new Clover() )->process( $coverage, self::$behat_run_dir . '/build/logs/behat-coverage.xml' );

Check warning on line 209 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L209

Added line #L209 was not covered by tests
}

/**
* Get the path to the Composer vendor folder.
*
Expand Down Expand Up @@ -298,7 +348,14 @@
];

$with_code_coverage = (string) getenv( 'WP_CLI_TEST_COVERAGE' );

if ( \in_array( $with_code_coverage, [ 'true', '1' ], true ) ) {
$has_coverage_driver = ( new Runtime() )->hasXdebug() || ( new Runtime() )->hasPCOV();

Check warning on line 353 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L353

Added line #L353 was not covered by tests

if ( ! $has_coverage_driver ) {
throw new RuntimeException( 'No coverage driver available. Re-run script with `--xdebug` flag, i.e. `composer behat -- --xdebug`.' );

Check warning on line 356 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L355-L356

Added lines #L355 - L356 were not covered by tests
}

$coverage_require_file = self::$behat_run_dir . '/vendor/wp-cli/wp-cli-tests/utils/generate-coverage.php';
if ( ! file_exists( $coverage_require_file ) ) {
// This file is not vendored inside the wp-cli-tests project
Expand Down Expand Up @@ -871,8 +928,8 @@
);

$this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/'
. uniqid( 'wp-cli-download-', true )
. '.phar';
. uniqid( 'wp-cli-download-', true )
. '.phar';

Check warning on line 932 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L931-L932

Added lines #L931 - L932 were not covered by tests

Process::create(
Utils\esc_cmd(
Expand Down Expand Up @@ -957,6 +1014,8 @@
$env['BEHAT_SCENARIO_TITLE'] = $this->scenario->getTitle();
}

$env['BEHAT_STEP_LINE'] = $this->step_line;

Check warning on line 1017 in src/Context/FeatureContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/FeatureContext.php#L1017

Added line #L1017 was not covered by tests

$env['WP_CLI_TEST_DBTYPE'] = self::$db_type;

if ( isset( $this->variables['RUN_DIR'] ) ) {
Expand Down
34 changes: 21 additions & 13 deletions utils/generate-coverage.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
<?php

/**
* This script is added via `--require` to the WP-CLI commands executed by the Behat test runner.
* This script is added via the `WP_CLI_REQUIRE` environment variable to the WP-CLI commands executed by the Behat test runner.
* It starts coverage collection right away and registers a shutdown hook to complete it
* after the respective WP-CLI command has finished.
*/

use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Driver\Selector;
use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\Report\Clover;
use SebastianBergmann\CodeCoverage\Report\PHP as PHPReport;

/*
* The names of the current feature and scenario are passed on from the Behat test runner
* to this script through environment variables.
*/
$feature = getenv( 'BEHAT_FEATURE_TITLE' );
$scenario = getenv( 'BEHAT_SCENARIO_TITLE' );
$step_line = (int) getenv( 'BEHAT_STEP_LINE' );
$name = "{$feature} - {$scenario} - {$step_line}";

/*
* Do not run coverage if they are empty, which means we are running some command
* during test preparation, e.g. the `wp core download` in `FeatureContext::prepare()`.
*/
if ( empty( $feature ) | empty( $scenario ) ) {
return;
}

$project_dir = (string) getenv( 'TEST_RUN_DIR' );

Expand Down Expand Up @@ -65,30 +81,22 @@ function ( $file ) {
$filter
);

/*
* The names of the current feature and scenario are passed on from the Behat test runner
* to this script through environment variables `BEHAT_FEATURE_TITLE` & `BEHAT_SCENARIO_TITLE`.
*/
$feature = getenv( 'BEHAT_FEATURE_TITLE' );
$scenario = getenv( 'BEHAT_SCENARIO_TITLE' );
$name = "{$feature} - {$scenario}";

$coverage->start( $name );

register_shutdown_function(
static function () use ( $coverage, $feature, $scenario, $name, $project_dir ) {
static function () use ( $coverage, $feature, $scenario, $step_line, $name, $project_dir ) {
$coverage->stop();

$feature_suffix = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $feature ) );
$scenario_suffix = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $scenario ) );
$db_type = strtolower( getenv( 'WP_CLI_TEST_DBTYPE' ) );
$destination = "$project_dir/build/logs/$feature_suffix-$scenario_suffix-$db_type.xml";
$destination = "$project_dir/build/logs/$feature_suffix-$scenario_suffix-$step_line-$db_type.cov";

$dir = dirname( $destination );
if ( ! file_exists( $dir ) ) {
mkdir( $dir, 0777, true /*recursive*/ );
}

( new Clover() )->process( $coverage, $destination, $name );
( new PHPReport() )->process( $coverage, $destination );
}
);