CodeSampleX

Exemplo

guzzlehttp/guzzle 8.0.2: Test code that calls an HTTP API with Guzzle, with no network and no monkeypatching

Amostra verificada para composer guzzlehttp/guzzle 8.0.2: Test code that calls an HTTP API with Guzzle, with no network and no monkeypatching. O contrato…

sha256:66d105189c76d32ccb87b901f8712d7a4836f4457091fb85af42cf277a9c0f30

Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu. Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas. MIT-0

Evidência de execução

O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.

Base da evidência
Contrato assinado aprovado
Recibos de verificação
2
Chaves de assinatura que o compilaram
2
Ambiente declarado php 8 linux x64 php 8 php composer

Ambientes das execuções de verificação

Ambiente Contrato Etapas Execução
php 8 · linux alpine/x64 · docker ed25519:a2ec939a4c60e243 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · composer@1
2026-08-14
php 8 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · composer@1
2026-08-18

Caso

HOW
Objetivo
Test code that calls an HTTP API with Guzzle, with no network and no monkeypatching
Pacotes
Símbolos
  • GuzzleHttp.Handler.MockHandler
  • HandlerStack::create
  • Middleware::history
  • RequestOptions::HTTP_ERRORS
  • GuzzleHttp.Exception.RequestException
  • GuzzleHttp.Exception.ResponseException
Ambiente
php 8
Criado
2026-08-14T09:42:37Z

Contrato

  1. assert a MockHandler queue serves its responses in order while base_uri, the query option and the default headers still apply, and that history holds every exchange while MockHandler::getLastRequest holds only the most recent
  2. assert the queue never looks at the request, so only the recorded request proves which method and endpoint were called
  3. assert base_uri is merged by reference resolution: a leading slash on the request path replaces the base path, and a base_uri without a trailing slash loses its last segment
  4. assert http_errors turns a 500 into a ServerException whose response body is still readable from its current position and whose exception code is the status
  5. assert getResponse and hasResponse are gone from RequestException so the guzzle 7 idiom is a fatal Error, and getResponse now lives on ResponseException with a non-nullable return type
  6. assert http_errors set to false returns the 500 response instead of throwing
  7. assert a queued throwable is thrown as the same object and carries no response side
  8. assert pushed history records the prepared request with Content-Length but records a 500 as a fulfilled response
  9. assert unshifted history records the ServerException but its captured request has no Content-Length
  10. assert a dry queue makes an async call return a rejected promise rather than throwing at the call site, and that waiting on it raises a plain OutOfBoundsException that is not a GuzzleException
  11. assert a bare HandlerStack built with new drops http_errors so a 500 comes back as a response

Arquivos

  • composer.json
  • composer.lock
  • csx.json
  • phpunit.xml
  • src/Api.php
  • test/ApiTest.php

Baixar o artefato de código-fonte (tar.gz)

Código-fonte

composer.json
{
  "name": "csx/guzzle-mock-handler",
  "license": "MIT-0",
  "require": {
    "guzzlehttp/guzzle": "8.0.2"
  },
  "require-dev": {
    "phpunit/phpunit": "13.3.1"
  },
  "autoload": {
    "psr-4": {
      "Csx\\": "src/"
    }
  },
  "config": {
    "platform": {
      "php": "8.5.0"
    }
  }
}
composer.lock (apenas o início)
{
    "_readme": [
        "This file locks the dependencies of your project to a known state",
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "c4b2419149968f2e8eeadf92cc1cae44",
    "packages": [
        {
            "name": "guzzlehttp/guzzle",
            "version": "8.0.2",
            "source": {
                "type": "git",
                "url": "https://github.com/guzzle/guzzle.git",
                "reference": "d1cbca76970939a9c2ced55b1e25ea26f34fc773"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d1cbca76970939a9c2ced55b1e25ea26f34fc773",
                "reference": "d1cbca76970939a9c2ced55b1e25ea26f34fc773",
                "shasum": ""
            },
            "require": {
                "ext-json": "*",
                "guzzlehttp/promises": "^3.0.1",
                "guzzlehttp/psr7": "^3.0",
                "php": "^7.4 || ^8.0",
                "psr/http-client": "^1.0",
                "psr/http-factory": "^1.0",
                "symfony/polyfill-php80": "^1.25",
                "symfony/polyfill-php82": "^1.27"
            },
            "provide": {
                "psr/http-client-implementation": "1.0"
            },
            "require-dev": {
                "bamarni/composer-bin-plugin": "^1.8.2",
                "ext-curl": "*",
                "guzzle/client-integration-tests": "4.0.1",
                "guzzlehttp/test-server": "^1.0",
                "php-http/message-factory": "^1.1",
                "phpunit/phpunit": "^9.6.34",
                "psr/log": "^1.1 || ^2.0 || ^3.0"
            },
            "suggest": {
                "ext-curl": "Required for CURL handler support",
                "ext-intl": "Required for Internationalized Domain Name (IDN) support",
                "psr/log": "Required for using the Log middleware"
            },
            "type": "library",
            "extra": {
                "bamarni-bin": {
                    "bin-links": true,
                    "forward-command": false
                }
            },
            "autoload": {
                "psr-4": {
                    "GuzzleHttp\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Graham Campbell",
                    "email": "hello@gjcampbell.co.uk",
                    "homepage": "https://github.com/GrahamCampbell"
                },
                {
                    "name": "Michael Dowling",
                    "email": "mtdowling@gmail.com",
                    "homepage": "https://github.com/mtdowling"
                },
                {
                    "name": "Jeremy Lindblom",
                    "email": "jeremeamia@gmail.com",
                    "homepage": "https://github.com/jeremeamia"
                },
                {
                    "name": "George Mponos",
                    "email": "gmponos@gmail.com",
                    "homepage": "https://github.com/gmponos"
                },
                {
                    "name": "Tobias Nyholm",
                    "email": "tobias.nyholm@gmail.com",
                    "homepage": "https://github.com/Nyholm"
                },
                {
                    "name": "Márk Sági-Kazár",
                    "email": "mark.sagikazar@gmail.com",
                    "homepage": "https://github.com/sagikazarmark"
                },
                {
                    "name": "Tobias Schultze",
                    "email": "webmaster@tubo-world.de",
                    "homepage": "https://github.com/Tobion"
                }
            ],
            "description": "Guzzle is a PHP HTTP client library",
            "keywords": [
                "client",
                "curl",
                "framework",
                "http",
                "http client",
                "psr-18",
                "psr-7",
                "rest",
                "web service"
            ],
            "support": {
                "issues": "https://github.com/guzzle/guzzle/issues",
                "source": "https://github.com/guzzle/guzzle/tree/8.0.2"
            },
            "funding": [
                {
                    "url": "https://github.com/GrahamCampbell",
                    "type": "github"
                },
                {
                    "url": "https://github.com/Nyholm",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-05T19:50:26+00:00"
        },
        {
            "name": "guzzlehttp/promises",
            "version": "3.0.1",
            "source": {
                "type": "git",
                "url": "https://github.com/guzzle/promises.git",
                "reference": "64f38b87fa7d371853804161bfc701c9bc2cc00a"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/guzzle/promises/zipball/64f38b87fa7d371853804161bfc701c9bc2cc00a",
                "reference": "64f38b87fa7d371853804161bfc701c9bc2cc00a",
                "shasum": ""
            },
            "require": {
                "php": "^7.4 || ^8.0"
            },
            "require-dev": {
                "bamarni/composer-bin-plugin": "^1.8.2",
                "phpunit/phpunit": "^9.6.34"
            },
            "type": "library",
            "extra": {
                "bamarni-bin": {
                    "bin-links": true,
                    "forward-command": false
                }
            },
            "autoload": {
                "psr-4": {
                    "GuzzleHttp\\Promise\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Graham Campbell",
                    "email": "hello@gjcampbell.co.uk",
                    "homepage": "https://github.com/GrahamCampbell"
                },
                {
                    "name": "Michael Dowling",
                    "email": "mtdowling@gmail.com",
                    "homepage": "https://github.com/mtdowling"
                },
                {
                    "name": "Tobias Nyholm",
                    "email": "tobias.nyholm@gmail.com",
                    "homepage": "https://github.com/Nyholm"
                },
                {
                    "name": "Tobias Schultze",
                    "email": "webmaster@tubo-world.de",
                    "homepage": "https://github.com/Tobion"
                }
            ],
            "description": "Guzzle promises library",
            "keywords": [
                "promise"
            ],
            "support": {
                "issues": "https://github.com/guzzle/promises/issues",
                "source": "https://github.com/guzzle/promises/tree/3.0.1"
            },
            "funding": [
                {
                    "url": "https://github.com/GrahamCampbell",
                    "type": "github"
                },
                {
                    "url": "https://github.com/Nyholm",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-05T19:35:04+00:00"
        },
        {
            "name": "guzzlehttp/psr7",
            "version": "3.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/guzzle/psr7.git",
                "reference": "b094ded77ee97a6027ad6cf0e8c7b9f88381814c"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/guzzle/psr7/zipball/b094ded77ee97a6027ad6cf0e8c7b9f88381814c",
                "reference": "b094ded77ee97a6027ad6cf0e8c7b9f88381814c",
                "shasum": ""
            },
            "require": {
                "php": "^7.4 || ^8.0",
                "psr/http-factory": "^1.1",
                "psr/http-message": "^2.0",
                "symfony/polyfill-php80": "^1.25",
                "symfony/polyfill-php82": "^1.27"
            },
            "provide": {
                "psr/http-factory-implementation": "1.1",
                "psr/http-message-implementation": "2.0"
            },
            "require-dev": {
                "bamarni/composer-bin-plugin": "^1.8.2",
                "http-interop/http-factory-tests": "1.1.0",
                "jshttp/mime-db": "1.54.0.1",
                "php-http/psr7-integration-tests": "^1.5.1",
                "phpunit/phpunit": "^9.6.34"
            },
            "suggest": {
                "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
            },
            "type": "library",
            "extra": {
                "bamarni-bin": {
                    "bin-links": true,
                    "forward-command": false
                }
            },
            "autoload": {
                "psr-4": {
                    "GuzzleHttp\\Psr7\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Graham Campbell",
                    "email": "hello@gjcampbell.co.uk",
                    "homepage": "https://github.com/GrahamCampbell"
                },
                {
                    "name": "Michael Dowling",
                    "email": "mtdowling@gmail.com",
                    "homepage": "https://github.com/mtdowling"
                },
                {
                    "name": "George Mponos",
                    "email": "gmponos@gmail.com",
                    "homepage": "https://github.com/gmponos"
                },
                {
                    "name": "Tobias Nyholm",
                    "email": "tobias.nyholm@gmail.com",
                    "homepage": "https://github.com/Nyholm"
                },
                {
                    "name": "Márk Sági-Kazár",
                    "email": "mark.sagikazar@gmail.com",
                    "homepage": "https://github.com/sagikazarmark"
                },
                {
                    "name": "Tobias Schultze",
                    "email": "webmaster@tubo-world.de",
                    "homepage": "https://github.com/Tobion"
                },
                {
                    "name": "Márk Sági-Kazár",
                    "email": "mark.sagikazar@gmail.com",
                    "homepage": "https://sagikazarmark.hu"
                }
            ],
            "description": "PSR-7 message implementation that also provides common utility methods",
            "keywords": [
                "http",
                "message",
                "psr-7",
                "request",
                "response",
                "stream",
                "uri",
                "url"
            ],
            "support": {
                "issues": "https://github.com/guzzle/psr7/issues",
                "source": "https://github.com/guzzle/psr7/tree/3.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/GrahamCampbell",
                    "type": "github"
                },
                {
                    "url": "https://github.com/Nyholm",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
                    "type": "tidelift"
                }
            ],
            "time": "2026-07-20T13:48:31+00:00"
        },
        {
            "name": "psr/http-client",
            "version": "1.0.3",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/http-client.git",
                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
                "shasum": ""
            },
            "require": {
                "php": "^7.0 || ^8.0",
                "psr/http-message": "^1.0 || ^2.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "1.0.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\Http\\Client\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "https://www.php-fig.org/"
                }
            ],
            "description": "Common interface for HTTP clients",
            "homepage": "https://github.com/php-fig/http-client",
            "keywords": [
                "http",
                "http-client",
                "psr",
                "psr-18"
            ],
            "support": {
                "source": "https://github.com/php-fig/http-client"
            },
            "time": "2023-09-23T14:17:50+00:00"
        },
        {
            "name": "psr/http-factory",
            "version": "1.1.0",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/http-factory.git",
                "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
                "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
                "shasum": ""
            },
            "require": {
                "php": ">=7.1",
                "psr/http-message": "^1.0 || ^2.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "1.0.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\Http\\Message\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "https://www.php-fig.org/"
                }
            ],
            "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
            "keywords": [
                "factory",
                "http",
                "message",
                "psr",
                "psr-17",
                "psr-7",
                "request",
                "response"
            ],
            "support": {
                "source": "https://github.com/php-fig/http-factory"
            },
            "time": "2024-04-15T12:06:14+00:00"
        },
        {
            "name": "psr/http-message",
            "version": "2.0",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/http-message.git",
                "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
                "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
                "shasum": ""
            },
            "require": {
                "php": "^7.2 || ^8.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "2.0.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\Http\\Message\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "https://www.php-fig.org/"
                }
            ],
            "description": "Common interface for HTTP messages",
            "homepage": "https://github.com/php-fig/http-message",
            "keywords": [
                "http",
                "http-message",
                "psr",
                "psr-7",
                "request",
                "response"
            ],
            "support": {
                "source": "https://github.com/php-fig/http-message/tree/2.0"
            },
            "time": "2023-04-04T09:54:51+00:00"
        },
        {
            "name": "symfony/polyfill-php80",
            "version": "v1.37.0",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-php80.git",
                "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
                "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Php80\\": ""
                },
                "classmap": [
                    "Resources/stubs"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Ion Bazan",
                    "email": "ion.bazan@gmail.com"
                },
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-04-10T16:19:22+00:00"
        },
        {
            "name": "symfony/polyfill-php82",
            "version": "v1.38.1",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-php82.git",
                "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b",
                "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Php82\\": ""
                },
                "classmap": [
                    "Resources/stubs"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill backporting some PHP 8.2+ features to lower PHP versions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-php82/tree/v1.38.1"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-05-26T12:45:58+00:00"
        }
    ],
    "packages-dev": [
        {
            "name": "myclabs/deep-copy",
            "version": "1.14.0",
            "source": {
                "type": "git",
                "url": "https://github.com/myclabs/DeepCopy.git",
                "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae",
                "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae",
                "shasum": ""
            },
            "require": {
                "php": "^8.0"
            },
            "conflict": {
                "doctrine/collections": "<1.6.8",
                "doctrine/common": "<2.13.3 || >=3 <3.2.2"
            },
            "require-dev": {
                "doctrine/collections": "^1.6.8",
                "doctrine/common": "^2.13.3 || ^3.2.2",
                "phpspec/prophecy": "^1.10",
                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
            },
            "type": "library",
            "autoload": {
                "files": [
                    "src/DeepCopy/deep_copy.php"
                ],
                "psr-4": {
                    "DeepCopy\\": "src/DeepCopy/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "description": "Create deep copies (clones) of your objects",
            "keywords": [
                "clone",
                "copy",
                "duplicate",
                "object",
                "object graph"
            ],
            "support": {
                "issues": "https://github.com/myclabs/DeepCopy/issues",
                "source": "https://github.com/myclabs/DeepCopy/tree/1.14.0"
            },
            "funding": [
                {
                    "url": "https://github.com/mnapoli",
                    "type": "github"
                }
            ],
            "time": "2026-08-11T10:17:44+00:00"
        },
        {
            "name": "nikic/php-parser",
            "version": "v5.8.0",
            "source": {
                "type": "git",
                "url": "https://github.com/nikic/PHP-Parser.git",
                "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
                "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
                "shasum": ""
            },
            "require": {
                "ext-json": "*",
                "ext-tokenizer": "*",
                "php": ">=7.4"
            },
            "require-dev": {
                "ircmaxell/php-yacc": "^0.0.7",
                "phpunit/phpunit": "^9.0"
            },
            "bin": [
                "bin/php-parse"
            ],
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "5.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "PhpParser\\": "lib/PhpParser"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Nikita Popov"
                }
            ],
            "description": "A PHP parser written in PHP",
            "keywords": [
                "parser",
                "php"
            ],
            "support": {
                "issues": "https://github.com/nikic/PHP-Parser/issues",
                "source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0"
            },
            "time": "2026-07-04T14:30:18+00:00"
        },
        {
            "name": "phar-io/manifest",
            "version": "2.0.4",
            "source": {
                "type": "git",
                "url": "https://github.com/phar-io/manifest.git",
                "reference": "54750ef60c58e43759730615a392c31c80e23176"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
                "reference": "54750ef60c58e43759730615a392c31c80e23176",
                "shasum": ""
            },
            "require": {
                "ext-dom": "*",
                "ext-libxml": "*",
                "ext-phar": "*",
                "ext-xmlwriter": "*",
                "phar-io/version": "^3.0.1",
                "php": "^7.2 || ^8.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "2.0.x-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Arne Blankerts",
                    "email": "arne@blankerts.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Heuer",
                    "email": "sebastian@phpeople.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "Developer"
                }
            ],
            "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
            "support": {
                "issues": "https://github.com/phar-io/manifest/issues",
                "source": "https://github.com/phar-io/manifest/tree/2.0.4"
            },
            "funding": [
                {
                    "url": "https://github.com/theseer",
                    "type": "github"
                }
            ],
            "time": "2024-03-03T12:33:53+00:00"
        },
        {
            "name": "phar-io/version",
            "version": "3.2.1",
            "source": {
                "type": "git",
                "url": "https://github.com/phar-io/version.git",
                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
                "shasum": ""
            },
            "require": {
                "php": "^7.2 || ^8.0"
            },
            "type": "library",
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Arne Blankerts",
                    "email": "arne@blankerts.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Heuer",
                    "email": "sebastian@phpeople.de",
                    "role": "Developer"
                },
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "Developer"
                }
            ],
            "description": "Library for handling version information and constraints",
            "support": {
                "issues": "https://github.com/phar-io/version/issues",
                "source": "https://github.com/phar-io/version/tree/3.2.1"
            },
            "time": "2022-02-21T01:04:05+00:00"
        },
        {
            "name": "phpunit/php-code-coverage",
            "version": "14.3.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
                "reference": "060a5c93e81afb01e97dbe8930a5d0c9bd46e54e"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/060a5c93e81afb01e97dbe8930a5d0c9bd46e54e",
                "reference": "060a5c93e81afb01e97dbe8930a5d0c9bd46e54e",
                "shasum": ""
            },
            "require": {
                "ext-dom": "*",
                "ext-libxml": "*",
                "ext-mbstring": "*",
                "ext-xmlwriter": "*",
                "nikic/php-parser": "^5.8.0",
                "php": ">=8.4",
                "phpunit/php-text-template": "^6.0",
                "sebastian/complexity": "^6.0",
                "sebastian/environment": "^9.3.2",
                "sebastian/git-state": "^1.0",
                "sebastian/lines-of-code": "^5.0.2",
                "sebastian/version": "^7.0",
                "theseer/tokenizer": "^2.0.1"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.3"
            },
            "suggest": {
                "ext-pcov": "PHP extension that provides line coverage",
                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "14.3.x-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
            "keywords": [
                "coverage",
                "testing",
                "xunit"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
                "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.3.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-07T07:24:15+00:00"
        },
        {
            "name": "phpunit/php-file-iterator",
            "version": "7.0.1",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
                "reference": "3ccaa29123548190af12fee7af078dcd7f3ddfab"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3ccaa29123548190af12fee7af078dcd7f3ddfab",
                "reference": "3ccaa29123548190af12fee7af078dcd7f3ddfab",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.3.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "7.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
            "keywords": [
                "filesystem",
                "iterator"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
                "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.1"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-10T06:43:12+00:00"
        },
        {
            "name": "phpunit/php-invoker",
            "version": "7.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/php-invoker.git",
                "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88",
                "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "ext-pcntl": "*",
                "phpunit/phpunit": "^13.0"
            },
            "suggest": {
                "ext-pcntl": "*"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "7.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Invoke callables with a timeout",
            "homepage": "https://github.com/sebastianbergmann/php-invoker/",
            "keywords": [
                "process"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
                "security": "https://github.com/sebastianbergmann/php-invoker/security/policy",
                "source": "https://github.com/sebastianbergmann/php-invoker/tree/7.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/phpunit/php-invoker",
                    "type": "tidelift"
                }
            ],
            "time": "2026-02-06T04:34:47+00:00"
        },
        {
            "name": "phpunit/php-text-template",
            "version": "6.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/php-text-template.git",
                "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/a47af19f93f76aa3368303d752aa5272ca3299f4",
                "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "6.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Simple template engine.",
            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
            "keywords": [
                "template"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
                "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
                "source": "https://github.com/sebastianbergmann/php-text-template/tree/6.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/phpunit/php-text-template",
                    "type": "tidelift"
                }
            ],
            "time": "2026-02-06T04:36:37+00:00"
        },
        {
            "name": "phpunit/php-timer",
            "version": "9.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/php-timer.git",
                "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a0e12065831f6ab0d83120dc61513eb8d9a966f6",
                "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "9.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Utility class for timing",
            "homepage": "https://github.com/sebastianbergmann/php-timer/",
            "keywords": [
                "timer"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/php-timer/issues",
                "security": "https://github.com/sebastianbergmann/php-timer/security/policy",
                "source": "https://github.com/sebastianbergmann/php-timer/tree/9.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/phpunit/php-timer",
                    "type": "tidelift"
                }
            ],
            "time": "2026-02-06T04:37:53+00:00"
        },
        {
            "name": "phpunit/phpunit",
            "version": "13.3.1",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/phpunit.git",
                "reference": "fc024931d6ad047404e9d86536735923fe63a06b"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc024931d6ad047404e9d86536735923fe63a06b",
                "reference": "fc024931d6ad047404e9d86536735923fe63a06b",
                "shasum": ""
            },
            "require": {
                "ext-dom": "*",
                "ext-filter": "*",
                "ext-json": "*",
                "ext-libxml": "*",
                "ext-mbstring": "*",
                "ext-xmlwriter": "*",
                "myclabs/deep-copy": "^1.14.0",
                "phar-io/manifest": "^2.0.4",
                "phar-io/version": "^3.2.1",
                "php": ">=8.4.1",
                "phpunit/php-code-coverage": "^14.3",
                "phpunit/php-file-iterator": "^7.0.1",
                "phpunit/php-invoker": "^7.0.0",
                "phpunit/php-text-template": "^6.0.0",
                "phpunit/php-timer": "^9.0.0",
                "sebastian/cli-parser": "^5.0.1",
                "sebastian/comparator": "^8.4",
                "sebastian/diff": "^9.0",
                "sebastian/environment": "^9.3.2",
                "sebastian/exporter": "^8.2.1",
                "sebastian/file-filter": "^1.0",
                "sebastian/git-state": "^1.0",
                "sebastian/global-state": "^9.0.1",
                "sebastian/object-enumerator": "^8.1.0",
                "sebastian/recursion-context": "^8.0.1",
                "sebastian/type": "^7.0.2",
                "sebastian/version": "^7.0.0",
                "staabm/side-effects-detector": "^1.0.5"
            },
            "bin": [
                "phpunit"
            ],
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "13.3-dev"
                }
            },
            "autoload": {
                "files": [
                    "src/Framework/Assert/Functions.php"
                ],
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "The PHP Unit Testing framework.",
            "homepage": "https://phpunit.de/",
            "keywords": [
                "phpunit",
                "testing",
                "xunit"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
                "source": "https://github.com/sebastianbergmann/phpunit/tree/13.3.1"
            },
            "funding": [
                {
                    "url": "https://phpunit.de/sponsoring.html",
                    "type": "other"
                }
            ],
            "time": "2026-08-13T13:14:23+00:00"
        },
        {
            "name": "sebastian/cli-parser",
            "version": "5.0.1",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/cli-parser.git",
                "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/eeb759ad3146b7096fb59c3195d39e071cd409e3",
                "reference": "eeb759ad3146b7096fb59c3195d39e071cd409e3",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.2.6"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "5.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Library for parsing CLI options",
            "homepage": "https://github.com/sebastianbergmann/cli-parser",
            "support": {
                "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
                "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
                "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.1"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-01T04:27:14+00:00"
        },
        {
            "name": "sebastian/comparator",
            "version": "8.4.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/comparator.git",
                "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/3b070e608146cba00fd6fd1f0ffba89e5a8897fb",
                "reference": "3b070e608146cba00fd6fd1f0ffba89e5a8897fb",
                "shasum": ""
            },
            "require": {
                "ext-dom": "*",
                "ext-mbstring": "*",
                "php": ">=8.4",
                "sebastian/diff": "^9.0",
                "sebastian/exporter": "^8.2"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.3"
            },
            "suggest": {
                "ext-bcmath": "For comparing BcMath\\Number objects"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "8.4-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de"
                },
                {
                    "name": "Jeff Welch",
                    "email": "whatthejeff@gmail.com"
                },
                {
                    "name": "Volker Dusch",
                    "email": "github@wallbash.com"
                },
                {
                    "name": "Bernhard Schussek",
                    "email": "bschussek@2bepublished.at"
                }
            ],
            "description": "Provides the functionality to compare PHP values for equality",
            "homepage": "https://github.com/sebastianbergmann/comparator",
            "keywords": [
                "comparator",
                "compare",
                "equality"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/comparator/issues",
                "security": "https://github.com/sebastianbergmann/comparator/security/policy",
                "source": "https://github.com/sebastianbergmann/comparator/tree/8.4.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
                    "type": "tidelift"
                }
            ],
            "time": "2026-08-07T07:23:13+00:00"
        },
        {
            "name": "sebastian/complexity",
            "version": "6.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/complexity.git",
                "reference": "c5651c795c98093480df79350cb050813fc7a2f3"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/c5651c795c98093480df79350cb050813fc7a2f3",
                "reference": "c5651c795c98093480df79350cb050813fc7a2f3",
                "shasum": ""
            },
            "require": {
                "nikic/php-parser": "^5.0",
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "6.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de",
                    "role": "lead"
                }
            ],
            "description": "Library for calculating the complexity of PHP code units",
            "homepage": "https://github.com/sebastianbergmann/complexity",
            "support": {
                "issues": "https://github.com/sebastianbergmann/complexity/issues",
                "security": "https://github.com/sebastianbergmann/complexity/security/policy",
                "source": "https://github.com/sebastianbergmann/complexity/tree/6.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/sebastian/complexity",
                    "type": "tidelift"
                }
            ],
            "time": "2026-02-06T04:41:32+00:00"
        },
        {
            "name": "sebastian/diff",
            "version": "9.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/diff.git",
                "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a3fb6a298a265ff487a91bbea46e03cd01dbb226",
                "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.2",
                "symfony/process": "^7.4.13"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "9.0-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de"
                },
                {
                    "name": "Kore Nordmann",
                    "email": "mail@kore-nordmann.de"
                }
            ],
            "description": "Diff implementation",
            "homepage": "https://github.com/sebastianbergmann/diff",
            "keywords": [
                "diff",
                "udiff",
                "unidiff",
                "unified diff"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/diff/issues",
                "security": "https://github.com/sebastianbergmann/diff/security/policy",
                "source": "https://github.com/sebastianbergmann/diff/tree/9.0.0"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/sebastian/diff",
                    "type": "tidelift"
                }
            ],
            "time": "2026-06-05T03:04:51+00:00"
        },
        {
            "name": "sebastian/environment",
            "version": "9.3.2",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/environment.git",
                "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e",
                "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.1.11"
            },
            "suggest": {
                "ext-posix": "*"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "9.3-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de"
                }
            ],
            "description": "Provides functionality to handle HHVM/PHP environments",
            "homepage": "https://github.com/sebastianbergmann/environment",
            "keywords": [
                "Xdebug",
                "environment",
                "hhvm"
            ],
            "support": {
                "issues": "https://github.com/sebastianbergmann/environment/issues",
                "security": "https://github.com/sebastianbergmann/environment/security/policy",
                "source": "https://github.com/sebastianbergmann/environment/tree/9.3.2"
            },
            "funding": [
                {
                    "url": "https://github.com/sebastianbergmann",
                    "type": "github"
                },
                {
                    "url": "https://liberapay.com/sebastianbergmann",
                    "type": "liberapay"
                },
                {
                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
                    "type": "thanks_dev"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/sebastian/environment",
                    "type": "tidelift"
                }
            ],
            "time": "2026-05-25T13:41:38+00:00"
        },
        {
            "name": "sebastian/exporter",
            "version": "8.2.1",
            "source": {
                "type": "git",
                "url": "https://github.com/sebastianbergmann/exporter.git",
                "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/24a3b69bba4a12ab615fca9d34680c5598d9ab7a",
                "reference": "24a3b69bba4a12ab615fca9d34680c5598d9ab7a",
                "shasum": ""
            },
            "require": {
                "ext-mbstring": "*",
                "php": ">=8.4",
                "sebastian/recursion-context": "^8.0.1"
            },
            "require-dev": {
                "phpunit/phpunit": "^13.3"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "8.2-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Sebastian Bergmann",
                    "email": "sebastian@phpunit.de"
                },
                {
                    "name": "Jeff Welch",
                    "email": "whatthejeff@gmail.com"
                },
                {
                    "name": "Volker Dusch",
                    "email": "github@wallbash.com"
                },
                {
                    "name": "Adam Harvey",
                    "email": "aharvey@php.net"
                },
                {
                    "name": "Bernhard Schussek",
                    "email": "bschussek@gmail.com"
                }
            ],
            "description": "Provides the functionality to export PHP variables for visualization",
            "h
csx.json
{"case":{"caseId":"case:sha256:79fb467acc0fac4149011bfae6ea40cba7666807b8fe6d09b3ba0268d3a71ee0","constraints":{"runtime":"php"},"contract":["assert a MockHandler queue serves its responses in order while base_uri, the query option and the default headers still apply, and that history holds every exchange while MockHandler::getLastRequest holds only the most recent","assert the queue never looks at the request, so only the recorded request proves which method and endpoint were called","assert base_uri is merged by reference resolution: a leading slash on the request path replaces the base path, and a base_uri without a trailing slash loses its last segment","assert http_errors turns a 500 into a ServerException whose response body is still readable from its current position and whose exception code is the status","assert getResponse and hasResponse are gone from RequestException so the guzzle 7 idiom is a fatal Error, and getResponse now lives on ResponseException with a non-nullable return type","assert http_errors set to false returns the 500 response instead of throwing","assert a queued throwable is thrown as the same object and carries no response side","assert pushed history records the prepared request with Content-Length but records a 500 as a fulfilled response","assert unshifted history records the ServerException but its captured request has no Content-Length","assert a dry queue makes an async call return a rejected promise rather than throwing at the call site, and that waiting on it raises a plain OutOfBoundsException that is not a GuzzleException","assert a bare HandlerStack built with new drops http_errors so a 500 comes back as a response"],"goal":"Test code that calls an HTTP API with Guzzle, with no network and no monkeypatching","kind":"HOW","packages":["pkg:composer/guzzlehttp/guzzle@8.0.2"],"schemaVersion":1,"symbols":["GuzzleHttp.Handler.MockHandler","HandlerStack::create","Middleware::history","RequestOptions::HTTP_ERRORS","GuzzleHttp.Exception.RequestException","GuzzleHttp.Exception.ResponseException"]},"contractCommand":["php","vendor/bin/phpunit","--colors=never"],"environment":{"arch":"x64","ecosystem":"composer","executionContext":"php","language":"php","os":"linux","packageManager":"composer","runtime":"php","runtimeVersion":"8","schemaVersion":1},"license":"MIT-0","packages":["pkg:composer/guzzlehttp/guzzle@8.0.2"],"schemaVersion":1,"symbols":["GuzzleHttp.Handler.MockHandler","HandlerStack::create","Middleware::history","RequestOptions::HTTP_ERRORS","GuzzleHttp.Exception.RequestException","GuzzleHttp.Exception.ResponseException"],"verifierAdapter":"composer@1"}
phpunit.xml
<?xml version="1.0"?>
<phpunit bootstrap="vendor/autoload.php" colors="false" recordTestRunHistory="false">
  <testsuites><testsuite name="csx"><directory>test</directory></testsuite></testsuites>
</phpunit>
src/Api.php
<?php

namespace Csx;

use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * Testing Guzzle 8 with no network, and the four things that are not what the
 * mock-transport habit or the Guzzle 7 docs lead you to expect.
 *
 * MockHandler is a queue, not a router. It never looks at the request: the
 * next entry comes back whatever method or URL you called, so a test can pass
 * while the code under test hits the wrong endpoint entirely. Proving what was
 * sent is a separate job, and there are two tools for it: getLastRequest() on
 * the MockHandler keeps only the most recent request, while the History
 * middleware keeps every exchange in order — which is why history is worth
 * pushing rather than treated as an optional extra. Running the queue dry is a
 * test-setup error rather than a transport error: MockHandler throws a plain
 * OutOfBoundsException that no GuzzleException catch block will see.
 *
 * Where history sits in the stack changes what it records, and both positions
 * are wrong for something. HandlerStack::create() has already pushed
 * http_errors and prepare_body, and resolve() wraps the stack from the end
 * inwards, so push() lands nearer the handler than anything create() added:
 *   - pushed  (inner): sees the Content-Length prepare_body added, but records
 *     a 500 as a fulfilled response with error => null, because http_errors
 *     converts it to a rejection further out.
 *   - unshifted (outer): records the ServerException in error, but the
 *     request it captured has no Content-Length yet.
 * Content-Type is on the request in both positions. In Guzzle 8 the json
 * option's conditional Content-Type is applied by Client::applyOptions before
 * any middleware runs, so unlike Content-Length it does not depend on
 * prepare_body — which no longer merges conditional headers at all.
 *
 * The handler you pass matters just as much. `new HandlerStack($mock)` is a
 * bare stack with no middleware, which means http_errors is silently inert: a
 * 500 comes back as a response and every error-path test passes for the wrong
 * reason. HandlerStack::create($mock) is what you want.
 *
 * Finally, the Guzzle 7 error-handling idiom is a fatal error on 8.
 * getResponse() and hasResponse() are gone from RequestException; getResponse()
 * now lives on ResponseException and is non-nullable. ServerException still
 * extends RequestException, so `catch (RequestException $e)` still catches a
 * 500 — it is the `$e->getResponse()` inside that catch block that dies.
 * Catch ResponseException (or BadResponseException) when you want the body.
 */
final class Api
{
    /**
     * Filled by the History middleware.
     *
     * @var list<array{request: RequestInterface, response: ?ResponseInterface, error: mixed, options: array}>
     */
    public array $history = [];

    public readonly Client $client;

    public readonly MockHandler $mock;

    /**
     * @param list<mixed> $queue responses, throwables, promises or callables
     * @param bool $recordOutermost unshift history instead of pushing it
     * @param string $baseUri whether the trailing slash is there is not cosmetic
     */
    public function __construct(
        array $queue = [],
        bool $recordOutermost = false,
        string $baseUri = 'https://api.example.com/v1/'
    ) {
        $this->mock = new MockHandler($queue);
        $stack = HandlerStack::create($this->mock);
        if ($recordOutermost) {
            $stack->unshift(Middleware::history($this->history));
        } else {
            $stack->push(Middleware::history($this->history));
        }
        $this->client = new Client([
            'handler' => $stack,
            // The trailing slash in the default is load-bearing. base_uri is
            // merged by RFC 3986 reference resolution, which drops the last
            // segment of a base path that does not end in one.
            'base_uri' => $baseUri,
            'headers' => ['X-Csx' => 'seed'],
        ]);
    }

    /** @return array<string, mixed> */
    public function fetchItems(int $page): array
    {
        $response = $this->client->get('items', [
            RequestOptions::QUERY => ['page' => $page, 'sort' => 'name'],
        ]);

        return json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR);
    }

    /** @param array<string, mixed> $payload */
    public function createItem(array $payload): ResponseInterface
    {
        return $this->client->post('items', [
            RequestOptions::JSON => $payload,
            RequestOptions::HEADERS => ['X-Request-Id' => 'r-1'],
        ]);
    }

    /** @param array<string, mixed> $options */
    public function get(string $path, array $options = []): ResponseInterface
    {
        return $this->client->get($path, $options);
    }

    public function lastRequest(): RequestInterface
    {
        return $this->history[count($this->history) - 1]['request'];
    }

    /**
     * The mistake worth being able to spot: a stack built with `new` carries
     * none of the default middleware, so http_errors never runs.
     *
     * @param list<mixed> $queue
     */
    public static function bareStackClient(array $queue): Client
    {
        return new Client([
            'handler' => new HandlerStack(new MockHandler($queue)),
            'base_uri' => 'https://api.example.com/v1/',
        ]);
    }
}
test/ApiTest.php
<?php

use Csx\Api;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ResponseException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\RequestOptions;
use PHPUnit\Framework\TestCase;

final class ApiTest extends TestCase
{
    public function testTheQueueIsServedInOrderAndTheRealClientStillRuns(): void
    {
        $api = new Api([
            new Response(200, ['Content-Type' => 'application/json'], '{"page":1}'),
            new Response(200, ['Content-Type' => 'application/json'], '{"page":2}'),
        ]);

        $this->assertSame(['page' => 1], $api->fetchItems(1));
        $this->assertSame(['page' => 2], $api->fetchItems(2));

        // Nothing about the client was stubbed out: base_uri resolution, the
        // query option and the default headers all ran for real.
        $this->assertSame(
            'https://api.example.com/v1/items?page=2&sort=name',
            (string) $api->lastRequest()->getUri()
        );
        $this->assertSame('seed', $api->lastRequest()->getHeaderLine('X-Csx'));
        $this->assertCount(0, $api->mock);

        // The MockHandler can answer "what was sent" too, but only for the
        // most recent request. History is what holds both exchanges.
        $this->assertCount(2, $api->history);
        $this->assertSame($api->lastRequest(), $api->mock->getLastRequest());
    }

    public function testTheQueueIsNotARouterAndNeverLooksAtTheRequest(): void
    {
        // The trap. MockHandler pops the next entry whatever you asked for, so
        // a test can pass while the code under test calls the wrong endpoint
        // with the wrong verb. Only the recorded request tells you what was
        // sent; the response proves nothing.
        $api = new Api([new Response(201, [], 'from the queue')]);

        $response = $api->client->request('DELETE', 'nothing/like/items');

        $this->assertSame(201, $response->getStatusCode());
        $this->assertSame('from the queue', (string) $response->getBody());
        $this->assertSame('DELETE', $api->lastRequest()->getMethod());
        $this->assertSame('/v1/nothing/like/items', $api->lastRequest()->getUri()->getPath());
    }

    public function testBaseUriIsMergedByReferenceResolutionNotConcatenation(): void
    {
        $api = new Api([new Response(200), new Response(200)]);

        $api->get('items');
        $this->assertSame('/v1/items', $api->history[0]['request']->getUri()->getPath());

        // Same-looking path, different URL: an absolute-path reference
        // replaces the base path instead of appending to it.
        $api->get('/items');
        $this->assertSame('/items', $api->history[1]['request']->getUri()->getPath());

        // And the trailing slash on base_uri is not decoration. Without it
        // "/v1" is the last segment rather than a directory, so resolution
        // drops it and the request silently leaves the API version behind.
        $unslashed = new Api([new Response(200)], baseUri: 'https://api.example.com/v1');
        $unslashed->get('items');
        $this->assertSame('/items', $unslashed->lastRequest()->getUri()->getPath());
    }

    public function testHttpErrorsTurnsA500IntoAServerExceptionThatKeepsTheBody(): void
    {
        $api = new Api([new Response(500, [], '{"error":"nope"}')]);

        try {
            $api->get('boom');
            $this->fail('a 500 should have thrown');
        } catch (ServerException $exception) {
            // The exception is the response holder, so the body survives the
            // throw and is still decodable — summarising it for the message
            // puts the stream position back where it found it.
            $this->assertSame(500, $exception->getResponse()->getStatusCode());
            $this->assertSame('{"error":"nope"}', $exception->getResponse()->getBody()->getContents());
            $this->assertSame('/v1/boom', $exception->getRequest()->getUri()->getPath());
            $this->assertStringContainsString('500 Internal Server Error', $exception->getMessage());
            // A ResponseException is constructed with the status as its code.
            $this->assertSame(500, $exception->getCode());
        }
    }

    public function testGetResponseIsNoLongerOnRequestExceptionInGuzzle8(): void
    {
        // Measured, and the opposite of every Guzzle 7 snippet: getResponse()
        // and hasResponse() are no longer declared on RequestException, and
        // hasResponse() is gone from the hierarchy outright.
        $this->assertFalse(method_exists(RequestException::class, 'getResponse'));
        $this->assertFalse(method_exists(RequestException::class, 'hasResponse'));
        $this->assertFalse(method_exists(ResponseException::class, 'hasResponse'));
        $this->assertTrue(method_exists(ResponseException::class, 'getResponse'));
        // getResponse() moved down to ResponseException, where the return type
        // is not nullable — a nullable one would stringify with a leading "?"
        // — so the `if ($e->hasResponse())` guard has nothing left to guard.
        $this->assertSame(
            'Psr\Http\Message\ResponseInterface',
            (string) (new ReflectionMethod(ResponseException::class, 'getResponse'))->getReturnType()
        );

        // So the documented Guzzle 7 idiom is a fatal Error on 8, not a
        // deprecation: nothing warns you, the call site just dies.
        $bare = new RequestException('connection reset', new Request('GET', 'https://api.example.com/v1/items'));
        try {
            $bare->getResponse();
            $this->fail('RequestException should no longer have getResponse');
        } catch (Error $error) {
            $this->assertSame(
                'Call to undefined method GuzzleHttp\Exception\RequestException::getResponse()',
                $error->getMessage()
            );
        }

        $api = new Api([new Response(500, [], '{"error":"nope"}')]);
        try {
            $api->get('boom');
            $this->fail('a 500 should have thrown');
        } catch (ResponseException $exception) {
            // ServerException extends BadResponseException extends
            // ResponseException extends RequestException, so an old
            // `catch (RequestException $e)` still fires on a 500. Catching the
            // class that declares getResponse is what makes the body readable
            // again without reflection or a hasResponse() guard.
            $this->assertInstanceOf(ServerException::class, $exception);
            $this->assertInstanceOf(BadResponseException::class, $exception);
            $this->assertInstanceOf(RequestException::class, $exception);
            $this->assertSame('{"error":"nope"}', (string) $exception->getResponse()->getBody());
        }
    }

    public function testHttpErrorsFalseGivesYouTheResponseInstead(): void
    {
        $api = new Api([new Response(500, [], '{"error":"nope"}')]);

        $response = $api->get('boom', [RequestOptions::HTTP_ERRORS => false]);

        $this->assertSame(500, $response->getStatusCode());
        $this->assertSame('{"error":"nope"}', (string) $response->getBody());
    }

    public function testAQueuedThrowableIsThrownExactlyAsQueued(): void
    {
        $queued = new RequestException(
            'connection reset',
            new Request('GET', 'https://api.example.com/v1/items')
        );
        $api = new Api([$queued]);

        try {
            $api->get('items');
            $this->fail('the queued exception should have been thrown');
        } catch (RequestException $exception) {
            // Not a copy and not re-wrapped: the same object comes back out,
            // which is how you test a transport failure with no network.
            $this->assertSame($queued, $exception);
            // A bare RequestException has no response side at all now, so
            // there is nothing to interrogate except the request.
            $this->assertNotInstanceOf(ResponseException::class, $exception);
            $this->assertSame('/v1/items', $exception->getRequest()->getUri()->getPath());
        }
    }

    public function testPushedHistoryRecordsThePreparedRequestButNotTheError(): void
    {
        $api = new Api([new Response(201, [], '{"id":7}')]);

        $api->createItem(['name' => 'widget', 'tags' => ['a']]);
        $request = $api->lastRequest();
        $body = (string) $request->getBody();

        $this->assertSame('POST', $request->getMethod());
        $this->assertSame('{"name":"widget","tags":["a"]}', $body);
        $this->assertSame('application/json', $request->getHeaderLine('Content-Type'));
        // Content-Length is prepare_body's contribution, and a pushed history
        // sits inside it, so this is the finished wire request.
        $this->assertSame((string) strlen($body), $request->getHeaderLine('Content-Length'));
        $this->assertSame('r-1', $request->getHeaderLine('X-Request-Id'));
        $this->assertSame('seed', $request->getHeaderLine('X-Csx'));
        $this->assertSame('GuzzleHttp/8', $request->getHeaderLine('User-Agent'));

        // The cost of that position: http_errors is further out, so the entry
        // for a failed exchange looks like a success.
        $failing = new Api([new Response(500, [], '{"error":"nope"}')]);
        try {
            $failing->get('boom');
        } catch (ServerException) {
        }
        $this->assertNull($failing->history[0]['error']);
        $this->assertSame(500, $failing->history[0]['response']->getStatusCode());
    }

    public function testUnshiftedHistoryRecordsTheErrorButLosesContentLength(): void
    {
        $api = new Api([new Response(201, [], '{"id":7}')], recordOutermost: true);

        $api->createItem(['name' => 'widget', 'tags' => ['a']]);
        $request = $api->lastRequest();

        // Same call, different recorded request, purely because of stack
        // position. Content-Type survives out here because the client applies
        // the json option's conditional header itself; Content-Length does not,
        // so asserting on it fails for a reason unrelated to the code
        // under test.
        $this->assertSame('{"name":"widget","tags":["a"]}', (string) $request->getBody());
        $this->assertSame('application/json', $request->getHeaderLine('Content-Type'));
        $this->assertFalse($request->hasHeader('Content-Length'));

        // What you gain: this side of http_errors, the failure is visible.
        $failing = new Api([new Response(500, [], '{"error":"nope"}')], recordOutermost: true);
        try {
            $failing->get('boom');
        } catch (ServerException) {
        }
        $this->assertInstanceOf(ServerException::class, $failing->history[0]['error']);
        $this->assertNull($failing->history[0]['response']);
    }

    public function testADryQueueRejectsWithAPlainOutOfBoundsException(): void
    {
        $api = new Api([new Response(200)]);
        $api->get('items');

        // Measured, against the assumption that a handler throwing means the
        // call site throws: Client::transfer catches everything the handler
        // raises and returns a rejected promise, so an async call comes back
        // normally and the failure only lands when the promise is waited on.
        $promise = $api->client->getAsync('items');
        $this->assertSame('rejected', $promise->getState());

        try {
            $promise->wait();
            $this->fail('the dry queue should have thrown');
        } catch (OutOfBoundsException $exception) {
            // A plain SPL exception, deliberately outside Guzzle's hierarchy,
            // because an empty queue is a broken test rather than a transport
            // failure — so a catch block for GuzzleException will not see it.
            $this->assertStringContainsString('Mock queue is empty', $exception->getMessage());
            $this->assertNotInstanceOf(GuzzleException::class, $exception);
        }
    }

    public function testABareHandlerStackSilentlyDropsHttpErrors(): void
    {
        // `new HandlerStack($mock)` carries none of the default middleware, so
        // http_errors never runs and every error-path test passes for the
        // wrong reason. HandlerStack::create is what makes the 500 above throw.
        $client = Api::bareStackClient([new Response(500, [], '{"error":"nope"}')]);

        $response = $client->get('boom');

        $this->assertSame(500, $response->getStatusCode());
    }
}

Seeder de origem

anonymous