From 7933e07a80f61686b717cb1c1001b6c068a6830c Mon Sep 17 00:00:00 2001 From: tedbow <tedbow@240860.no-reply.drupal.org> Date: Tue, 19 Apr 2022 22:00:13 +0000 Subject: [PATCH] Issue #3276072 by tedbow: UpdateReleaseValidator doesn't handle legacy version numbers --- .../src/ExtensionUpdater.php | 26 +-- .../src/LegacyVersionUtility.php | 84 ++++++++ .../src/Validator/UpdateReleaseValidator.php | 27 ++- .../release-history/aaa_update_test.1.1.xml | 184 ++++++++++++++++++ .../tests/src/Functional/UpdaterFormTest.php | 46 +++-- .../Validator/UpdateReleaseValidatorTest.php | 23 ++- .../src/Unit/LegacyVersionUtilityTest.php | 75 +++++++ 7 files changed, 415 insertions(+), 50 deletions(-) create mode 100644 automatic_updates_extensions/src/LegacyVersionUtility.php create mode 100644 automatic_updates_extensions/tests/fixtures/release-history/aaa_update_test.1.1.xml create mode 100644 automatic_updates_extensions/tests/src/Unit/LegacyVersionUtilityTest.php diff --git a/automatic_updates_extensions/src/ExtensionUpdater.php b/automatic_updates_extensions/src/ExtensionUpdater.php index c40d4b7c0f..5fc6e2057a 100644 --- a/automatic_updates_extensions/src/ExtensionUpdater.php +++ b/automatic_updates_extensions/src/ExtensionUpdater.php @@ -37,7 +37,7 @@ class ExtensionUpdater extends Stage { foreach ($project_versions as $project_name => $version) { $package = "drupal/$project_name"; $group = array_key_exists($package, $require_dev) ? 'dev' : 'production'; - $package_versions[$group][$package] = static::convertToSemanticVersion($version); + $package_versions[$group][$package] = LegacyVersionUtility::convertToSemanticVersion($version); } // Ensure that package versions are available to pre-create event @@ -92,28 +92,4 @@ class ExtensionUpdater extends Stage { } } - /** - * Converts version numbers to semantic versions if needed. - * - * @param string $project_version - * The version number. - * - * @return string - * The version number, converted if needed. - */ - private static function convertToSemanticVersion(string $project_version): string { - if (stripos($project_version, '8.x-') === 0) { - $project_version = substr($project_version, 4); - $version_parts = explode('-', $project_version); - $project_version = $version_parts[0] . '.0'; - if (count($version_parts) === 2) { - $project_version .= '-' . $version_parts[1]; - } - return $project_version; - } - else { - return $project_version; - } - } - } diff --git a/automatic_updates_extensions/src/LegacyVersionUtility.php b/automatic_updates_extensions/src/LegacyVersionUtility.php new file mode 100644 index 0000000000..d2daffa440 --- /dev/null +++ b/automatic_updates_extensions/src/LegacyVersionUtility.php @@ -0,0 +1,84 @@ +<?php + +namespace Drupal\automatic_updates_extensions; + +use Drupal\Core\Extension\ExtensionVersion; + +/** + * A utility class for dealing with legacy version numbers. + * + * @internal + * This is an internal utility class that could change in any release and + * should not be used by external code. + */ +final class LegacyVersionUtility { + + /** + * Converts a version number to a semantic version if needed. + * + * @param string $version + * The version number. + * + * @return string + * The version number, converted if needed. + */ + public static function convertToSemanticVersion(string $version): string { + if (self::isLegacyVersion($version)) { + $version = substr($version, 4); + $version_parts = explode('-', $version); + $version = $version_parts[0] . '.0'; + if (count($version_parts) === 2) { + $version .= '-' . $version_parts[1]; + } + return $version; + } + else { + return $version; + } + } + + /** + * Converts a version number to a legacy version if needed and possible. + * + * @param string $version_string + * The version number. + * + * @return string + * The version number, converted if needed, or NULL if not possible. Only + * semantic version numbers that have patch level of 0 can be converted into + * legacy version numbers. + */ + public static function convertToLegacyVersion($version_string): ?string { + if (self::isLegacyVersion($version_string)) { + return $version_string; + } + $version = ExtensionVersion::createFromVersionString($version_string); + if ($extra = $version->getVersionExtra()) { + $version_string_without_extra = str_replace("-$extra", '', $version_string); + } + else { + $version_string_without_extra = $version_string; + } + [,, $patch] = explode('.', $version_string_without_extra); + // A semantic version can only be converted to legacy if it's patch level is + // '0'. + if ($patch !== '0') { + return NULL; + } + return '8.x-' . $version->getMajorVersion() . '.' . $version->getMinorVersion() . ($extra ? "-$extra" : ''); + } + + /** + * Determines if a version is legacy. + * + * @param string $version + * The version number. + * + * @return bool + * TRUE if the version is a legacy version number, otherwise FALSE. + */ + private static function isLegacyVersion(string $version): bool { + return stripos($version, '8.x-') === 0; + } + +} diff --git a/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php b/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php index 994ac31e6a..15c581ee11 100644 --- a/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php +++ b/automatic_updates_extensions/src/Validator/UpdateReleaseValidator.php @@ -4,6 +4,7 @@ namespace Drupal\automatic_updates_extensions\Validator; use Drupal\automatic_updates\ProjectInfo; use Drupal\automatic_updates_extensions\ExtensionUpdater; +use Drupal\automatic_updates_extensions\LegacyVersionUtility; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\package_manager\Event\PreCreateEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -31,18 +32,38 @@ class UpdateReleaseValidator implements EventSubscriberInterface { $all_versions = $stage->getPackageVersions(); $messages = []; foreach (['production', 'dev'] as $package_type) { - foreach ($all_versions[$package_type] as $package_name => $version) { + foreach ($all_versions[$package_type] as $package_name => $sematic_version) { $package_parts = explode('/', $package_name); $project_name = $package_parts[1]; // If the version isn't in the list of installable releases, then it // isn't secure and supported and the user should receive an error. $releases = (new ProjectInfo($project_name))->getInstallableReleases(); - if (empty($releases) || !array_key_exists($version, $releases)) { + $is_missing_version = FALSE; + if (empty($releases)) { + $is_missing_version = TRUE; + } + elseif (!array_key_exists($sematic_version, $releases)) { + $legacy_version = LegacyVersionUtility::convertToLegacyVersion($sematic_version); + if ($legacy_version) { + if (!array_key_exists($legacy_version, $releases)) { + // If we cannot find the version using semantic or legacy then the + // version is missing. + $is_missing_version = TRUE; + } + } + else { + // If we cannot convert the semantic version into a legacy version + // then the version is missing. + $is_missing_version = TRUE; + } + } + if ($is_missing_version) { $messages[] = $this->t('Project @project_name to version @version', [ '@project_name' => $project_name, - '@version' => $version, + '@version' => $sematic_version, ]); } + } } if ($messages) { diff --git a/automatic_updates_extensions/tests/fixtures/release-history/aaa_update_test.1.1.xml b/automatic_updates_extensions/tests/fixtures/release-history/aaa_update_test.1.1.xml new file mode 100644 index 0000000000..2451a4bd4f --- /dev/null +++ b/automatic_updates_extensions/tests/fixtures/release-history/aaa_update_test.1.1.xml @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Test legacy versions --> +<project xmlns:dc="http://purl.org/dc/elements/1.1/"> +<title>AAA Update test</title> +<short_name>aaa_update_test</short_name> +<dc:creator>Drupal</dc:creator> +<supported_branches>8.x-2.,8.x-1.</supported_branches> +<project_status>published</project_status> +<link>http://example.com/project/aaa_update_test</link> + <terms> + <term><name>Projects</name><value>AAA Update test project</value></term> + </terms> +<releases> + <release> + <name>AAA Update test 8.x-3.0</name> + <version>8.x-3.0</version> + <tag>8.x-3.0</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-3-0-release</release_link> + <download_link>http://example.com/aaa_update_test-8-3-0.tar.gz</download_link> + <date>1584195300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.1</name> + <version>8.x-2.1</version> + <tag>8.x-2.1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-1.tar.gz</download_link> + <date>1581603300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.1-beta1</name> + <version>8.x-2.1-beta1</version> + <tag>8.x-2.1-beta1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-1-beta1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-1-beta1.tar.gz</download_link> + <date>1579011300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.1-alpha1</name> + <version>8.x-2.1-alpha1</version> + <tag>8.x-2.1-alpha1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-1-alpha1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-1-alpha1.tar.gz</download_link> + <date>1576419300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.0</name> + <version>8.x-2.0</version> + <tag>8.x-2.0</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-0-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-0.tar.gz</download_link> + <date>1573827300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.0-beta1</name> + <version>8.x-2.0-beta1</version> + <tag>8.x-2.0-beta1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-0-beta1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-0-beta1.tar.gz</download_link> + <date>1571235300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-2.0-alpha1</name> + <version>8.x-2.0-alpha1</version> + <tag>8.x-2.0-alpha1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-2-0-alpha1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-2-0-alpha1.tar.gz</download_link> + <date>1568643300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.1</name> + <version>8.x-1.1</version> + <tag>8.x-1.1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-1.tar.gz</download_link> + <date>1566051300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.1-beta1</name> + <version>8.x-1.1-beta1</version> + <tag>8.x-1.1-beta1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-1-beta1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-1-beta1.tar.gz</download_link> + <date>1563459300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.1-alpha1</name> + <version>8.x-1.1-alpha1</version> + <tag>8.x-1.1-alpha1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-1-alpha1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-1-alpha1.tar.gz</download_link> + <date>1560867300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.0</name> + <version>8.x-1.0</version> + <tag>8.x-1.0</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-0-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-0.tar.gz</download_link> + <date>1558275300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.0-beta1</name> + <version>8.x-1.0-beta1</version> + <tag>8.x-1.0-beta1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-0-beta1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-0-beta1.tar.gz</download_link> + <date>1555683300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> + <release> + <name>AAA Update test 8.x-1.0-alpha1</name> + <version>8.x-1.0-alpha1</version> + <tag>8.x-1.0-alpha1</tag> + <status>published</status> + <release_link>http://example.com/aaa_update_test-8-x-1-0-alpha1-release</release_link> + <download_link>http://example.com/aaa_update_test-8-x-1-0-alpha1.tar.gz</download_link> + <date>1553091300</date> + <terms> + <term><name>Release type</name><value>New features</value></term> + <term><name>Release type</name><value>Bug fixes</value></term> + </terms> + </release> +</releases> +</project> diff --git a/automatic_updates_extensions/tests/src/Functional/UpdaterFormTest.php b/automatic_updates_extensions/tests/src/Functional/UpdaterFormTest.php index a5ed47c6c6..5a3cb665f5 100644 --- a/automatic_updates_extensions/tests/src/Functional/UpdaterFormTest.php +++ b/automatic_updates_extensions/tests/src/Functional/UpdaterFormTest.php @@ -35,6 +35,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { 'automatic_updates_extensions', 'block', 'semver_test', + 'aaa_update_test', ]; /** @@ -47,13 +48,13 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { /** * Data provider for testSuccessfulUpdate(). * - * @return bool[] + * @return array[] * The test cases. */ - public function providerMaintanceMode() { + public function providerSuccessfulUpdate() { return [ - 'maintiance_mode_on' => [TRUE], - 'maintiance_mode_off' => [FALSE], + 'maintiance_mode_on, semver' => [TRUE, 'semver_test', '8.1.0', '8.1.1'], + 'maintiance_mode_off, legacy' => [FALSE, 'aaa_update_test', '8.x-2.0', '8.x-2.1'], ]; } @@ -97,9 +98,16 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { /** * Asserts the table shows the updates. + * + * @param string $expected_project_title + * The expected project title. + * @param string $expected_installed_version + * The expected installed version. + * @param string $expected_update_version + * The expected update version. */ - private function assertTableShowsUpdates() { - $this->assertUpdateTableRow($this->assertSession(), 'Semver Test', '8.1.0', '8.1.1'); + private function assertTableShowsUpdates(string $expected_project_title, string $expected_installed_version, string $expected_update_version): void { + $this->assertUpdateTableRow($this->assertSession(), $expected_project_title, $expected_installed_version, $expected_update_version); } /** @@ -107,11 +115,19 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { * * @param bool $maintenance_mode_on * Whether maintenance should be on at the beginning of the update. + * @param string $project_name + * The project name. + * @param string $installed_version + * The installed version. + * @param string $update_version + * The update version. * - * @dataProvider providerMaintanceMode + * @dataProvider providerSuccessfulUpdate */ - public function testSuccessfulUpdate(bool $maintenance_mode_on): void { - $this->setProjectInstalledVersion('8.1.0'); + public function testSuccessfulUpdate(bool $maintenance_mode_on, string $project_name, string $installed_version, string $update_version): void { + $this->updateProject = $project_name; + $this->setReleaseMetadata(__DIR__ . "/../../fixtures/release-history/$project_name.1.1.xml"); + $this->setProjectInstalledVersion($installed_version); $this->checkForUpdates(); $state = $this->container->get('state'); $state->set('system.maintenance_mode', $maintenance_mode_on); @@ -120,7 +136,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { // Navigate to the automatic updates form. $this->drupalGet('/admin/reports/updates'); $this->clickLink('Update Extensions'); - $this->assertTableShowsUpdates(); + $this->assertTableShowsUpdates( + $project_name === 'semver_test' ? 'Semver Test' : 'AAA Update test', + $installed_version, + $update_version + ); $page->checkField('projects[' . $this->updateProject . ']'); $page->pressButton('Update'); $this->checkForMetaRefresh(); @@ -154,7 +174,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $user = $this->createUser(['administer software updates']); $this->drupalLogin($user); $this->drupalGet('admin/reports/updates/automatic-update-extensions'); - $this->assertTableShowsUpdates(); + $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1'); $assert->pageTextContains('Automatic Updates Form'); $assert->buttonExists('Update'); } @@ -189,7 +209,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->setProjectInstalledVersion('8.1.0'); $this->checkForUpdates(); $this->drupalGet('admin/reports/updates/automatic-update-extensions'); - $this->assertTableShowsUpdates(); + $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1'); $message = t("You've not experienced Shakespeare until you have read him in the original Klingon."); $error = ValidationResult::createError([$message]); TestSubscriber1::setTestResult([$error], ReadinessCheckEvent::class); @@ -213,7 +233,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { // Navigate to the automatic updates form. $this->drupalGet('/admin/reports/updates'); $this->clickLink('Update Extensions'); - $this->assertTableShowsUpdates(); + $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1'); $assert->pageTextContains(static::$warningsExplanation); $assert->pageTextNotContains(static::$errorsExplanation); $assert->buttonExists('Update'); diff --git a/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php b/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php index 4c6fccfaef..de0f6e2eb0 100644 --- a/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php +++ b/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\automatic_updates_extensions\Kernel\Valdiator; +use Drupal\automatic_updates_extensions\LegacyVersionUtility; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\ValidationResult; use Drupal\Tests\automatic_updates_extensions\Kernel\AutomaticUpdatesExtensionsKernelTestBase; @@ -16,6 +17,8 @@ class UpdateReleaseValidatorTest extends AutomaticUpdatesExtensionsKernelTestBas /** * Tests updating to a release. * + * @param string $project + * The project to update. * @param string $installed_version * The installed version of the project. * @param string $update_version @@ -25,20 +28,20 @@ class UpdateReleaseValidatorTest extends AutomaticUpdatesExtensionsKernelTestBas * * @dataProvider providerTestRelease */ - public function testRelease(string $installed_version, string $update_version, bool $error_expected) { - $this->enableModules(['semver_test']); - $module_info = ['version' => $installed_version, 'project' => 'semver_test']; + public function testRelease(string $project, string $installed_version, string $update_version, bool $error_expected) { + $this->enableModules([$project]); + $module_info = ['version' => $installed_version, 'project' => $project]; $this->config('update_test.settings') - ->set("system_info.semver_test", $module_info) + ->set("system_info.$project", $module_info) ->save(); $this->setReleaseMetadataForProjects([ - 'semver_test' => __DIR__ . '/../../../fixtures/release-history/semver_test.1.1.xml', + $project => __DIR__ . "/../../../fixtures/release-history/$project.1.1.xml", 'drupal' => __DIR__ . '/../../../../../tests/fixtures/release-history/drupal.9.8.2.xml', ]); if ($error_expected) { $expected_results = [ ValidationResult::createError( - ["Project semver_test to version $update_version"], + ["Project $project to version " . LegacyVersionUtility::convertToSemanticVersion($update_version)], t('Cannot update because the following project version is not in the list of installable releases.') ), ]; @@ -47,7 +50,7 @@ class UpdateReleaseValidatorTest extends AutomaticUpdatesExtensionsKernelTestBas $expected_results = []; } - $this->assertUpdaterResults(['semver_test' => $update_version], $expected_results, PreCreateEvent::class); + $this->assertUpdaterResults([$project => $update_version], $expected_results, PreCreateEvent::class); } /** @@ -58,8 +61,10 @@ class UpdateReleaseValidatorTest extends AutomaticUpdatesExtensionsKernelTestBas */ public function providerTestRelease() { return [ - 'supported update' => ['8.1.0', '8.1.1', FALSE], - 'update to unsupported branch' => ['8.1.0', '8.2.0', TRUE], + 'semver, supported update' => ['semver_test', '8.1.0', '8.1.1', FALSE], + 'semver, update to unsupported branch' => ['semver_test', '8.1.0', '8.2.0', TRUE], + 'legacy, supported update' => ['aaa_update_test', '8.x-2.0', '8.x-2.1', FALSE], + 'legacy, update to unsupported branch' => ['aaa_update_test', '8.x-2.0', '8.x-3.0', TRUE], ]; } diff --git a/automatic_updates_extensions/tests/src/Unit/LegacyVersionUtilityTest.php b/automatic_updates_extensions/tests/src/Unit/LegacyVersionUtilityTest.php new file mode 100644 index 0000000000..df52a4b2b5 --- /dev/null +++ b/automatic_updates_extensions/tests/src/Unit/LegacyVersionUtilityTest.php @@ -0,0 +1,75 @@ +<?php + +namespace Drupal\Tests\automatic_updates_extensions\Unit; + +use Drupal\automatic_updates_extensions\LegacyVersionUtility; +use Drupal\Tests\UnitTestCase; + +/** + * @coversDefaultClass \Drupal\automatic_updates_extensions\LegacyVersionUtility + * + * @group automatic_updates_extensions + */ +class LegacyVersionUtilityTest extends UnitTestCase { + + /** + * @covers ::convertToSemanticVersion + * + * @param string $version_number + * The version number to covert. + * @param string $expected + * The expected result. + * + * @dataProvider providerConvertToSemanticVersion + */ + public function testConvertToSemanticVersion(string $version_number, string $expected) { + $this->assertSame($expected, LegacyVersionUtility::convertToSemanticVersion($version_number)); + } + + /** + * Data provider for testConvertToSemanticVersion() + * + * @return string[][] + * The test cases. + */ + public function providerConvertToSemanticVersion() { + return [ + '8.x-1.2' => ['8.x-1.2', '1.2.0'], + '8.x-1.2-alpha1' => ['8.x-1.2-alpha1', '1.2.0-alpha1'], + '1.2.0' => ['1.2.0', '1.2.0'], + '1.2.0-alpha1' => ['1.2.0-alpha1', '1.2.0-alpha1'], + ]; + } + + /** + * @covers ::convertToLegacyVersion + * + * @param string $version_number + * The version number to covert. + * @param string|null $expected + * The expected result. + * + * @dataProvider providerConvertToLegacyVersion + */ + public function testConvertToLegacyVersion(string $version_number, ?string $expected) { + $this->assertSame($expected, LegacyVersionUtility::convertToLegacyVersion($version_number)); + } + + /** + * Data provider for testConvertToLegacyVersion() + * + * @return array[] + * The test cases. + */ + public function providerConvertToLegacyVersion() { + return [ + '1.2.0' => ['1.2.0', '8.x-1.2'], + '1.2.0-alpha1' => ['1.2.0-alpha1', '8.x-1.2-alpha1'], + '8.x-1.2' => ['8.x-1.2', '8.x-1.2'], + '8.x-1.2-alpha1' => ['8.x-1.2-alpha1', '8.x-1.2-alpha1'], + '1.2.3' => ['1.2.3', NULL], + '1.2.3-alpha1' => ['1.2.3-alpha1', NULL], + ]; + } + +} -- GitLab