pest icon indicating copy to clipboard operation
pest copied to clipboard

[Bug]: pest --init detects laravel/framework in plain php application when Herd is installed

Open tpraxl opened this issue 7 months ago • 0 comments

What Happened

I set up a simple plain php application with pest (see below for bash setup and resulting composer.json). Then I ran vendor/bin/pest --init.

The generated code is for laravel (contains use Illuminate\Foundation\Testing\TestCase as BaseTestCase;) and does not work.

$ vendor/bin/pest
  Error 

  Class "Illuminate\Foundation\Testing\TestCase" not found

  at tests/TestCase.php:7
      3▕ namespace Tests;
      4▕ 
      5▕ use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
      6▕ 
  ➜   7▕ abstract class TestCase extends BaseTestCase
      8▕ {
      9▕     //
     10▕ }
     11▕ 

      +2 vendor frames 

  3   [internal]:0
      Composer\Autoload\ClassLoader::loadClass("Tests\TestCase")
      +2 vendor frames 

  6   tests/Pest.php:16
      Pest\PendingCalls\UsesCall::__destruct()

I expect pest not to detect laravel, and instead use the stubs for PhpUnit (use PHPUnit\Framework\TestCase as BaseTestCase;)

How to Reproduce

I have Laravel Herd installed (v1.20.3) on a Mac, using php 8.4.8 and composer 2.8.9.

Setup bash:

$ composer init --name=thomas/test --require-dev=pestphp/pest:^3.8 --autoload=src --no-interaction
Writing ./composer.json
PSR-4 autoloading configured. Use "namespace Thomas\Test;" in src
Include the Composer autoloader with: require 'vendor/autoload.php';

$ composer install
...
Do you trust "pestphp/pest-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
...

$ vendor/bin/pest --init

Resulting composer.json:

{
    "name": "thomas/test",
    "require-dev": {
        "pestphp/pest": "^3.8"
    },
    "autoload": {
        "psr-4": {
            "Thomas\\Test\\": "src"
        }
    },
    "require": {},
    "config": {
        "allow-plugins": {
            "pestphp/pest-plugin": true
        }
    }
}

Sample Repository

No response

Pest Version

3.8.2

PHP Version

8.4.8

Operation System

macOS

Notes

I set up a test script to dig into the problem:

$ composer require composer-runtime-api

$ cat src/info.php

<?php

require_once 'vendor/autoload.php';

use Composer\InstalledVersions;

var_dump(InstalledVersions::isInstalled('laravel/framework'));
var_dump(InstalledVersions::getInstallPath('laravel/framework'));

$ php src/info.php
bool(true)
string(101) "phar:///Applications/Herd.app/Contents/Resources/valet/dump.phar/vendor/composer/../laravel/framework"

This clearly shows that InstalledVersions::isInstalled gives the wrong result. It seems not to be limited to local dependencies.

However, adding false as the second parameter ($includeDevRequirements), yields the expected result for me:

var_dump(InstalledVersions::isInstalled('laravel/framework', false));

// output:
// bool(false)
// string(101) "phar:///Applications/Herd.app/Contents/Resources/valet/dump.phar/vendor/composer/../laravel/framework"

So, maybe this could be fixed here, by adding a second boolean parameter: https://github.com/pestphp/pest/blob/3.x/src/Plugins/Init.php#L122

However, this would most likely not be an actual fix. I think the base problem is a missing composer php API to ignore global requirements when querying installed packages.

tpraxl avatar Jun 26 '25 09:06 tpraxl