Problem/Motivation

Adding return types to runtime code has BC concerns, but adding to test code should be straightforward and can be at least partially automated with rector.

My suggestion would be to do, for core/tests:

Proposed resolution

Remove baseline entries and manually add missing return types and other fixes for Kernel tests.

Note that some of the failures come from usage in tests of traits that live in the runtime namespaces, and cannot be fixed in this issue.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3579189

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Status: Active » Needs review
mondrake’s picture

Status: Needs review » Needs work
mondrake’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Pretty straight forward, no objections to the changes.

xjm’s picture

Status: Reviewed & tested by the community » Needs review

This issue has many of the changes I'd expect -- simply adding void typehints to test method signatures -- but then there are other changes like this:

   * Tests retrieval of component names from locale default config storage.
   */
  public function testGetComponentNames(): void {
    $languageManager = \Drupal::languageManager();
    $this->assertInstanceOf(ConfigurableLanguageManagerInterface::class, $languageManager);

    $storage = new LocaleDefaultConfigStorage(
      new NullStorage(),
      \Drupal::languageManager(),
      $languageManager,
      'testing',
    );

Or this:

   * Tests retrieval of component names from locale default config storage.
   */
  public function testGetComponentNames(): void {
    $languageManager = \Drupal::languageManager();
    $this->assertInstanceOf(ConfigurableLanguageManagerInterface::class, $languageManager);

    $storage = new LocaleDefaultConfigStorage(
      new NullStorage(),
      \Drupal::languageManager(),
      $languageManager,
      'testing',
    );

...And then there are things like switching assertEquals() to assertSame(), which is a different scope of typing in tests. Or:

  /**
   * The previous untranslatable field value.
   *
   * @var string[]
   * @var array<string,?string>
   */

...Note actually a typehint at all, but a docblock.

This is one of those merge requests that is much easier to generate from static analysis than it is to review, because each of these different cases needs separate evaluation. TLDR, this issue has scope-crept a lot from the original scope described in the IS and should be split up accordingly. :)

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

mondrake’s picture

rebased and added types to base class properties and some of the traits

mondrake’s picture

Status: Needs work » Needs review

anyone willing tackle #7 and split this up, feel free.

mstrelan’s picture

TLDR, this issue has scope-crept a lot from the original scope described in the IS and should be split up accordingly. :)

I'm not so sure about that, the proposed resolution says:

Remove baseline entries and manually add missing return types and other fixes for Kernel tests.

smustgrave’s picture

The change to testGetComponentNames does seem weird but is it a blocker for this ticket?

mondrake’s picture

#12 yes, that solves this baseline entry:

$ignoreErrors[] = [
	'message' => '#^Parameter \\#2 \\$language_manager of class Drupal\\\\locale\\\\LocaleDefaultConfigStorage constructor expects Drupal\\\\language\\\\ConfigurableLanguageManagerInterface, Drupal\\\\Core\\\\Language\\\\LanguageManagerInterface given\\.$#',
	'identifier' => 'argument.type',
	'count' => 1,
	'path' => __DIR__ . '/modules/locale/tests/src/Kernel/LocaleDefaultConfigStorageTest.php',
];

That happens because \Drupal has this

  /**
   * Returns the language manager service.
   *
   * @return \Drupal\Core\Language\LanguageManagerInterface
   *   The language manager.
   */
  public static function languageManager() {
    return static::getContainer()->get('language_manager');
  }

while Drupal\locale\LocaleDefaultConfigStorage expects

  /**
   * Constructs a LocaleDefaultConfigStorage.
   *
   * @param \Drupal\Core\Config\StorageInterface $config_storage
   *   The storage object to use for reading configuration data.
   * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
   *   The language manager.
   * @param string $install_profile
   *   The current installation profile.
   */
  public function __construct(StorageInterface $config_storage, ConfigurableLanguageManagerInterface $language_manager, $install_profile) {
    $this->configStorage = $config_storage;
    $this->languageManager = $language_manager;

    $this->requiredInstallStorage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_INSTALL_DIRECTORY, ExtensionInstallStorage::DEFAULT_COLLECTION, TRUE, $install_profile);
    $this->optionalInstallStorage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_OPTIONAL_DIRECTORY, ExtensionInstallStorage::DEFAULT_COLLECTION, TRUE, $install_profile);
  }

in fact I think \Drupal is wrong (otherwise we would get a TypeError, as the parameter is strictly typed in the constructor), but I did not want to change \Drupal, here it's only about test code. Splitting the code in a variable assignment and asserting the inheritance on the variable makes PHPStan be confident we are not passing a wrongly typed parameter.

Please, add comments inline on the MR if possible, it's easier to see the context.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Your explanation makes sense to me.

mondrake’s picture

Actually - checked a bit.

\Drupal is right. Drupal\Core\Language\LanguageManagerInterface is an ancestor of the Drupal\language\ConfigurableLanguageManager, that implements the additional Drupal\language\ConfigurableLanguageManagerInterface interface.

So it's right that \Drupal::languageManager() returns the topmost interface. The language module then overrides the standard manager with its own class, so the concrete class returned will be the replaced one that implements both interfaces.

But since Drupal\locale\LocaleDefaultConfigStorage requires ConfigurableLanguageManagerInterface the assertInstanceOf is IMHO the proper 'type narrowing' action to take.

longwave’s picture

Status: Reviewed & tested by the community » Needs review

Can we change the type in the LocaleDefaultConfigStorage constructor? The only usage is

$this->languageManager->getStandardLanguageList()

and that method is on the parent LanguageManagerInterface interface - it doesn't seem to need ConfigurableLanguageManagerInterface?

mondrake’s picture

#16 if it's OK to change runtime code in this MR, sure we can, done in latest commit.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Feedback from @longwave appears to be addressed.

  • longwave committed 65586432 on main
    test: #3579189 Fix return types and baselined errors of core/tests/...
longwave’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 65586432e25 to main. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.