Compare commits
2 Commits
master
...
5e8edeac9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e8edeac9f | ||
|
|
c1e8294f77 |
40
.github/workflows/build.yml
vendored
40
.github/workflows/build.yml
vendored
@@ -50,6 +50,46 @@ jobs:
|
|||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: composer test
|
run: composer test
|
||||||
|
|
||||||
|
symfony8-php85-consumer-install:
|
||||||
|
name: Symfony 8 + PHP 8.5 consumer install
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
coverage: none
|
||||||
|
ini-values: "memory_limit=-1"
|
||||||
|
php-version: '8.5'
|
||||||
|
tools: composer:v2
|
||||||
|
|
||||||
|
- name: Verify installability in a Symfony 8 consumer project
|
||||||
|
run: |
|
||||||
|
mkdir /tmp/fob-symfony8-consumer
|
||||||
|
cat > /tmp/fob-symfony8-consumer/composer.json <<'JSON'
|
||||||
|
{
|
||||||
|
"name": "friends-of-behat/symfony8-consumer-probe",
|
||||||
|
"type": "project",
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"repositories": [
|
||||||
|
{"type": "path", "url": "${{ github.workspace }}", "options": {"symlink": false}}
|
||||||
|
],
|
||||||
|
"require-dev": {
|
||||||
|
"behat/behat": "4.x-dev",
|
||||||
|
"friends-of-behat/symfony-extension": "*",
|
||||||
|
"symfony/framework-bundle": "^8.0",
|
||||||
|
"symfony/yaml": "^8.0"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
composer update --working-dir=/tmp/fob-symfony8-consumer --no-interaction --no-plugins --prefer-dist --no-progress
|
||||||
|
|
||||||
psalm:
|
psalm:
|
||||||
name: Run Psalm
|
name: Run Psalm
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,3 +1,17 @@
|
|||||||
|
# CHANGELOG FOR `2.3.x`
|
||||||
|
|
||||||
|
## v2.3.0 (unreleased)
|
||||||
|
|
||||||
|
#### TL;DR
|
||||||
|
|
||||||
|
- **Added installability support for Symfony 8 and PHP 8.5**.
|
||||||
|
|
||||||
|
#### Details
|
||||||
|
|
||||||
|
- Allow `symfony/dependency-injection` and `symfony/http-kernel` `^8.0`.
|
||||||
|
- Allow Behat `^4.0`, which is required by Symfony 8 because Behat 3.x only supports Symfony components up to 7.x.
|
||||||
|
- Keep Symfony 7.4 / Behat 3.31 compatibility and add a CI consumer-install probe for Symfony 8 on PHP 8.5.
|
||||||
|
|
||||||
# CHANGELOG FOR `2.1.x`
|
# CHANGELOG FOR `2.1.x`
|
||||||
|
|
||||||
## v2.2.0 (2021-02-04)
|
## v2.2.0 (2021-02-04)
|
||||||
|
|||||||
16
behat.dist.php
Normal file
16
behat.dist.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Behat\Config\Config;
|
||||||
|
use Behat\Config\Profile;
|
||||||
|
use Behat\Config\Suite;
|
||||||
|
use Tests\Behat\Context\TestContext;
|
||||||
|
|
||||||
|
return (new Config())
|
||||||
|
->withProfile((new Profile('default'))
|
||||||
|
->withSuite((new Suite('default'))
|
||||||
|
->withContexts(TestContext::class),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
;
|
||||||
@@ -11,23 +11,23 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.3",
|
"php": ">=8.3 <8.6",
|
||||||
"behat/behat": "^3.22",
|
"behat/behat": "^3.31 || ^4.0",
|
||||||
"symfony/dependency-injection": "^7.4",
|
"symfony/dependency-injection": "^7.4 || ^8.0",
|
||||||
"symfony/http-kernel": "^7.4"
|
"symfony/http-kernel": "^7.4 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"behat/mink-browserkit-driver": "^2.0",
|
"behat/mink-browserkit-driver": "^2.0",
|
||||||
"behat/mink-selenium2-driver": "^1.3",
|
"behat/mink-selenium2-driver": "^1.3",
|
||||||
"behat/mink": "^1.9",
|
"behat/mink": "^1.9",
|
||||||
"friends-of-behat/mink-extension": "^2.5",
|
"friends-of-behat/mink-extension": "^2.5",
|
||||||
"friends-of-behat/page-object-extension": "^0.3.2",
|
"friends-of-behat/page-object-extension": "^0.4",
|
||||||
"friends-of-behat/service-container-extension": "^1.1",
|
"friends-of-behat/service-container-extension": "^2.0",
|
||||||
"sylius-labs/coding-standard": ">=4.1.1, <=4.2.1",
|
"sylius-labs/coding-standard": ">=4.1.1, <=4.2.1",
|
||||||
"symfony/browser-kit": "^7.4",
|
"symfony/browser-kit": "^7.4 || ^8.0",
|
||||||
"symfony/framework-bundle": "^7.4",
|
"symfony/framework-bundle": "^7.4 || ^8.0",
|
||||||
"symfony/process": "^7.4",
|
"symfony/process": "^7.4 || ^8.0",
|
||||||
"symfony/yaml": "^7.4",
|
"symfony/yaml": "^7.4 || ^8.0",
|
||||||
"vimeo/psalm": "^6.0"
|
"vimeo/psalm": "^6.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "2.2-dev"
|
"dev-master": "2.3-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ declare(strict_types=1);
|
|||||||
namespace Tests\Behat\Context;
|
namespace Tests\Behat\Context;
|
||||||
|
|
||||||
use Behat\Behat\Context\Context;
|
use Behat\Behat\Context\Context;
|
||||||
|
use Behat\Hook\AfterScenario as AfterScenarioHook;
|
||||||
|
use Behat\Hook\BeforeFeature as BeforeFeatureHook;
|
||||||
|
use Behat\Hook\BeforeScenario as BeforeScenarioHook;
|
||||||
|
use Behat\Step\Given as GivenStep;
|
||||||
|
use Behat\Step\Then as ThenStep;
|
||||||
|
use Behat\Step\When as WhenStep;
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
use Symfony\Component\Process\PhpExecutableFinder;
|
use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
@@ -28,8 +34,9 @@ final class TestContext implements Context
|
|||||||
private $variables = [];
|
private $variables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @BeforeFeature
|
* BeforeFeature
|
||||||
*/
|
*/
|
||||||
|
#[BeforeFeatureHook]
|
||||||
public static function beforeFeature(): void
|
public static function beforeFeature(): void
|
||||||
{
|
{
|
||||||
self::$workingDir = sprintf('%s/%s/', sys_get_temp_dir(), uniqid('', true));
|
self::$workingDir = sprintf('%s/%s/', sys_get_temp_dir(), uniqid('', true));
|
||||||
@@ -38,8 +45,9 @@ final class TestContext implements Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @BeforeScenario
|
* BeforeScenario
|
||||||
*/
|
*/
|
||||||
|
#[BeforeScenarioHook]
|
||||||
public function beforeScenario(): void
|
public function beforeScenario(): void
|
||||||
{
|
{
|
||||||
self::$filesystem->remove(self::$workingDir);
|
self::$filesystem->remove(self::$workingDir);
|
||||||
@@ -47,16 +55,18 @@ final class TestContext implements Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @AfterScenario
|
* AfterScenario
|
||||||
*/
|
*/
|
||||||
|
#[AfterScenarioHook]
|
||||||
public function afterScenario(): void
|
public function afterScenario(): void
|
||||||
{
|
{
|
||||||
self::$filesystem->remove(self::$workingDir);
|
self::$filesystem->remove(self::$workingDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given a standard Symfony autoloader configured
|
* Given a standard Symfony autoloader configured
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('a standard Symfony autoloader configured')]
|
||||||
public function standardSymfonyAutoloaderConfigured(): void
|
public function standardSymfonyAutoloaderConfigured(): void
|
||||||
{
|
{
|
||||||
$this->thereIsFile('vendor/autoload.php', sprintf(<<<'CON'
|
$this->thereIsFile('vendor/autoload.php', sprintf(<<<'CON'
|
||||||
@@ -74,8 +84,9 @@ CON
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given a working Symfony application with SymfonyExtension configured
|
* Given a working Symfony application with SymfonyExtension configured
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('a working Symfony application with SymfonyExtension configured')]
|
||||||
public function workingSymfonyApplicationWithExtension(): void
|
public function workingSymfonyApplicationWithExtension(): void
|
||||||
{
|
{
|
||||||
$this->thereIsConfiguration(
|
$this->thereIsConfiguration(
|
||||||
@@ -217,24 +228,27 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^an? (server|environment) variable "([^"]++)" set to "([^"]++)"$/
|
* Given /^an? (server|environment) variable "([^"]++)" set to "([^"]++)"$/
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('/^an? (server|environment) variable "([^"]++)" set to "([^"]++)"$/')]
|
||||||
public function variableSetTo(string $type, string $name, string $value): void
|
public function variableSetTo(string $type, string $name, string $value): void
|
||||||
{
|
{
|
||||||
$this->variables[$type][$name] = $value;
|
$this->variables[$type][$name] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^a YAML services file containing:$/
|
* Given /^a YAML services file containing:$/
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('/^a YAML services file containing:$/')]
|
||||||
public function yamlServicesFile($content): void
|
public function yamlServicesFile($content): void
|
||||||
{
|
{
|
||||||
$this->thereIsFile('config/services.yaml', (string) $content);
|
$this->thereIsFile('config/services.yaml', (string) $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/
|
* Given /^a Behat configuration containing(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('/^a Behat configuration containing(?: "([^"]+)"|:)$/')]
|
||||||
public function thereIsConfiguration($content): void
|
public function thereIsConfiguration($content): void
|
||||||
{
|
{
|
||||||
$mainConfigFile = sprintf('%s/behat.yml', self::$workingDir);
|
$mainConfigFile = sprintf('%s/behat.yml', self::$workingDir);
|
||||||
@@ -250,11 +264,64 @@ YML
|
|||||||
$mainBehatConfiguration['imports'][] = $newConfigFile;
|
$mainBehatConfiguration['imports'][] = $newConfigFile;
|
||||||
|
|
||||||
self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration));
|
self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration));
|
||||||
|
$this->dumpPhpConfigurationBridge($mainConfigFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dumpPhpConfigurationBridge(string $yamlConfigFile): void
|
||||||
|
{
|
||||||
|
self::$filesystem->dumpFile(
|
||||||
|
sprintf('%s/behat.dist.php', self::$workingDir),
|
||||||
|
sprintf(
|
||||||
|
<<<'PHP'
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$load = static function (string $file): array {
|
||||||
|
$configuration = \Symfony\Component\Yaml\Yaml::parseFile($file);
|
||||||
|
$imports = $configuration['imports'] ?? [];
|
||||||
|
unset($configuration['imports']);
|
||||||
|
|
||||||
|
foreach ($imports as $import) {
|
||||||
|
$importedConfiguration = \Symfony\Component\Yaml\Yaml::parseFile($import);
|
||||||
|
$configuration = array_replace_recursive($configuration, $importedConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
$extensionClassMap = [
|
||||||
|
'FriendsOfBehat\\SymfonyExtension' => 'FriendsOfBehat\\SymfonyExtension\\ServiceContainer\\SymfonyExtension',
|
||||||
|
'Behat\\MinkExtension' => 'Behat\\MinkExtension\\ServiceContainer\\MinkExtension',
|
||||||
|
'FriendsOfBehat\\ServiceContainerExtension' => 'FriendsOfBehat\\ServiceContainerExtension\\ServiceContainer\\ServiceContainerExtension',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($configuration as &$profileConfiguration) {
|
||||||
|
if (!is_array($profileConfiguration['extensions'] ?? null)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($extensionClassMap as $legacyName => $className) {
|
||||||
|
if (!array_key_exists($legacyName, $profileConfiguration['extensions'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profileConfiguration['extensions'][$className] = $profileConfiguration['extensions'][$legacyName];
|
||||||
|
unset($profileConfiguration['extensions'][$legacyName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $configuration;
|
||||||
|
};
|
||||||
|
|
||||||
|
return new \Behat\Config\Config($load(%s));
|
||||||
|
PHP
|
||||||
|
, var_export($yamlConfigFile, true),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^a (?:.+ |)file "([^"]+)" containing(?: "([^"]+)"|:)$/
|
* Given /^a (?:.+ |)file "([^"]+)" containing(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('/^a (?:.+ |)file "([^"]+)" containing(?: "([^"]+)"|:)$/')]
|
||||||
public function thereIsFile($file, $content): string
|
public function thereIsFile($file, $content): string
|
||||||
{
|
{
|
||||||
$path = self::$workingDir . '/' . $file;
|
$path = self::$workingDir . '/' . $file;
|
||||||
@@ -265,16 +332,18 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Given /^a feature file containing(?: "([^"]+)"|:)$/
|
* Given /^a feature file containing(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[GivenStep('/^a feature file containing(?: "([^"]+)"|:)$/')]
|
||||||
public function thereIsFeatureFile($content): void
|
public function thereIsFeatureFile($content): void
|
||||||
{
|
{
|
||||||
$this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content);
|
$this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @When /^I run Behat$/
|
* When /^I run Behat$/
|
||||||
*/
|
*/
|
||||||
|
#[WhenStep('/^I run Behat$/')]
|
||||||
public function iRunBehat(): void
|
public function iRunBehat(): void
|
||||||
{
|
{
|
||||||
$executablePath = BEHAT_BIN_PATH;
|
$executablePath = BEHAT_BIN_PATH;
|
||||||
@@ -301,8 +370,9 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^it should pass$/
|
* Then /^it should pass$/
|
||||||
*/
|
*/
|
||||||
|
#[ThenStep('/^it should pass$/')]
|
||||||
public function itShouldPass(): void
|
public function itShouldPass(): void
|
||||||
{
|
{
|
||||||
if (0 === $this->getProcessExitCode()) {
|
if (0 === $this->getProcessExitCode()) {
|
||||||
@@ -315,8 +385,9 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^it should pass with(?: "([^"]+)"|:)$/
|
* Then /^it should pass with(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[ThenStep('/^it should pass with(?: "([^"]+)"|:)$/')]
|
||||||
public function itShouldPassWith($expectedOutput): void
|
public function itShouldPassWith($expectedOutput): void
|
||||||
{
|
{
|
||||||
$this->itShouldPass();
|
$this->itShouldPass();
|
||||||
@@ -324,8 +395,9 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^it should fail$/
|
* Then /^it should fail$/
|
||||||
*/
|
*/
|
||||||
|
#[ThenStep('/^it should fail$/')]
|
||||||
public function itShouldFail(): void
|
public function itShouldFail(): void
|
||||||
{
|
{
|
||||||
if (0 !== $this->getProcessExitCode()) {
|
if (0 !== $this->getProcessExitCode()) {
|
||||||
@@ -338,8 +410,9 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^it should fail with(?: "([^"]+)"|:)$/
|
* Then /^it should fail with(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[ThenStep('/^it should fail with(?: "([^"]+)"|:)$/')]
|
||||||
public function itShouldFailWith($expectedOutput): void
|
public function itShouldFailWith($expectedOutput): void
|
||||||
{
|
{
|
||||||
$this->itShouldFail();
|
$this->itShouldFail();
|
||||||
@@ -347,8 +420,9 @@ YML
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^it should end with(?: "([^"]+)"|:)$/
|
* Then /^it should end with(?: "([^"]+)"|:)$/
|
||||||
*/
|
*/
|
||||||
|
#[ThenStep('/^it should end with(?: "([^"]+)"|:)$/')]
|
||||||
public function itShouldEndWith($expectedOutput): void
|
public function itShouldEndWith($expectedOutput): void
|
||||||
{
|
{
|
||||||
$this->assertOutputMatches((string) $expectedOutput);
|
$this->assertOutputMatches((string) $expectedOutput);
|
||||||
|
|||||||
Reference in New Issue
Block a user