샘플
monolog/monolog 3.9.0: Upgrade a Monolog handler from 2 to 3 when records became LogRecord objects
검증된 샘플 — composer monolog/monolog 3.9.0: Upgrade a Monolog handler from 2 to 3 when records became LogRecord objects. php 8 · linux alpine/x64 · docker에서…
sha256:01f8118921bdd76c2acee316b2c81f508152d0fa45d432fa38ab667e764524e1
이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다.
통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다.
MIT-0
실행 증거
선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.
- 증거 기준
- 서명된 컨트랙트 통과
- 검증 영수증
- 2
- 빌드한 서명 키
- 2
선언된 환경
php 8 linux x64 php 8 php composer
검증 실행 환경
| 환경 | 컨트랙트 | 단계 | 실행일 |
|---|---|---|---|
| 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-17 |
케이스
MIGRATION- 목표
- Upgrade a Monolog handler from 2 to 3 when records became LogRecord objects
- 심벌
-
- Monolog.LogRecord
- Monolog.Level
- Logger::WARNING
- TestHandler::hasWarningThatContains
- 환경
- php 8
- 생성일
- 2026-08-14T06:15:03Z
컨트랙트
- assert the integer level constants were not removed and still equal the enum values
- assert a record is a LogRecord object so is_array stops matching
- assert array-style reads still work, which is why the migration looks complete
- assert record->datetime is a DateTimeImmutable subclass rather than the class itself
파일
- composer.json
- composer.lock
- csx.json
- phpunit.xml
- src/Records.php
- test/RecordsTest.php
소스
{
"name": "csx/monolog-3-record",
"license": "MIT-0",
"require": {
"monolog/monolog": "3.9.0"
},
"require-dev": {
"phpunit/phpunit": "13.3.1"
},
"autoload": {
"psr-4": {
"Csx\\": "src/"
}
},
"config": {
"platform": {
"php": "8.5.0"
}
}
}
{
"_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": "77226b0180f4bd0c6ca181a00c2ccbfb",
"packages": [
{
"name": "monolog/monolog",
"version": "3.9.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"php-console/php-console": "^3.1.8",
"phpstan/phpstan": "^2",
"phpstan/phpstan-deprecation-rules": "^2",
"phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "^10.5.17 || ^11.0.7",
"predis/predis": "^1.1 || ^2",
"rollbar/rollbar": "^4.0",
"ruflin/elastica": "^7 || ^8",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
},
"funding": [
{
"url": "https://github.com/Seldaek",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
"type": "tidelift"
}
],
"time": "2025-03-24T10:02:05+00:00"
},
{
"name": "psr/log",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.2"
},
"time": "2024-09-11T13:17:53+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",
"homepage": "https://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"security": "https://github.com/sebastianbergmann/exporter/security/policy",
"source": "https://github.com/sebastianbergmann/exporter/tree/8.2.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/exporter",
"type": "tidelift"
}
],
"time": "2026-08-07T07:22:06+00:00"
},
{
"name": "sebastian/file-filter",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/file-filter.git",
"reference": "33a26f394330f6faa7684bb9cc73afb7727aae93"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/file-filter/zipball/33a26f394330f6faa7684bb9cc73afb7727aae93",
"reference": "33a26f394330f6faa7684bb9cc73afb7727aae93",
"shasum": ""
},
"require": {
"php": ">=8.4"
},
"require-dev": {
"phpunit/phpunit": "^13.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.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 filtering files",
"homepage": "https://github.com/sebastianbergmann/file-filter",
"support": {
"issues": "https://github.com/sebastianbergmann/file-filter/issues",
"security": "https://github.com/sebastianbergmann/file-filter/security/policy",
"source": "https://github.com/sebastianbergmann/file-filter/tree/1.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/file-filter",
"type": "tidelift"
}
],
"time": "2026-04-22T07:20:04+00:00"
},
{
"name": "sebastian/git-state",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/git-state.git",
"reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/git-state/zipball/792a952e0eba55b6960a48aeceb9f371aad1f76b",
"reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b",
"shasum": ""
},
"require": {
"php": ">=8.4"
},
"require-dev": {
"phpunit/phpunit": "^13.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.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 describing the state of a Git checkout",
"homepage": "https://github.com/sebastianbergmann/git-state",
"support": {
"issues": "https://github.com/sebastianbergmann/git-state/issues",
"security": "https://github.com/sebastianbergmann/git-state/security/policy",
"source": "https://github.com/sebastianbergmann/git-state/tree/1.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/git-state",
"type": "tidelift"
}
],
"time": "2026-03-21T12:54:28+00:00"
},
{
"name": "sebastian/global-state",
"version": "9.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ba68ba79da690cf7eddefd3ce5b78b20b9ba9945",
"reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945",
"shasum": ""
},
"require": {
"php": ">=8.4",
"sebastian/object-reflector": "^6.0",
"sebastian/recursion-context": "^8.0"
},
"require-dev": {
"ext-dom": "*",
"phpunit/phpunit": "^13.1.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"
}
],
"description": "Snapshotting of global state",
"homepage": "https://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"security": "https://github.com/sebastianbergmann/global-state/security/policy",
"source": "https://github.com/sebastianbergmann/global-state/tree/9.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/global-state",
"type": "tidelift"
}
],
"time": "2026-06-01T15:11:33+00:00"
},
{
"name": "sebastian/lines-of-code",
"version": "5.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
"reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d1b6f8fce682505dbd048977f1abedf1b8ad3ff8",
"reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8",
"shasum": ""
},
"require": {
"nikic/php-parser": "^5.8.0",
"php": ">=8.4"
},
"require-dev": {
"phpunit/phpunit": "^13.2.4"
},
"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 counting the lines of code in PHP source code",
"homepage": "https://github.com/sebastianbergmann/lines-of-code",
"support": {
"issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
"security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
"source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.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/lines-of-code",
"type": "tidelift"
}
],
"time": "2026-07-09T08:42:34+00:00"
},
{
"name": "sebastian/object-enumerator",
"version": "8.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
"reference": "511064ecde82bd747e2ba2fab3dda8d977b59576"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/511064ecde82bd747e2ba2fab3dda8d977b59576",
"reference": "511064ecde82bd747e2ba2fab3dda8d977b59576",
"shasum": ""
},
"require": {
"php": ">=8.4",
"sebastian/recursion-context": "^8.0.1"
},
"require-dev": {
"phpunit/phpunit": "^13.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "8.1-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
"security": "https://github.com/sebastianbergmann/object-enumerator/security/policy",
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/8.1.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/object-enumerator",
"type": "tidelift"
}
],
"time": "2026-08-13T07:05:05+00:00"
},
{
"name": "sebastian/object-reflector",
"version": "6.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
"reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/f71bbcdc4f95456b4622810bec64eb06372e25b2",
"reference": "f71bbcdc4f95456b4622810bec64eb06372e25b2",
"shasum": ""
},
"require": {
"php": ">=8.4"
},
"require-dev": {
"phpunit/phpunit": "^13.3.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"
}
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
"security": "https://github.com/sebastianbergmann/object-reflector/security/policy",
"source": "https://github.com/sebastianbergmann/object-reflector/tree/6.1.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"
},
{"case":{"caseId":"case:sha256:c23356bd2d25999aee588921306bf9d85b1f248993b7cd306c61427e42a6e419","constraints":{"runtime":"php"},"contract":["assert the integer level constants were not removed and still equal the enum values","assert a record is a LogRecord object so is_array stops matching","assert array-style reads still work, which is why the migration looks complete","assert record-\u003edatetime is a DateTimeImmutable subclass rather than the class itself"],"goal":"Upgrade a Monolog handler from 2 to 3 when records became LogRecord objects","kind":"MIGRATION","packages":["pkg:composer/monolog/monolog@3.9.0"],"schemaVersion":1,"symbols":["Monolog.LogRecord","Monolog.Level","Logger::WARNING","TestHandler::hasWarningThatContains"]},"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/monolog/monolog@3.9.0"],"schemaVersion":1,"symbols":["Monolog.LogRecord","Monolog.Level","Logger::WARNING","TestHandler::hasWarningThatContains"],"verifierAdapter":"composer@1"}
<?xml version="1.0"?>
<phpunit bootstrap="vendor/autoload.php" colors="false" recordTestRunHistory="false">
<testsuites><testsuite name="csx"><directory>test</directory></testsuite></testsuites>
</phpunit>
<?php
namespace Csx;
use Monolog\Handler\TestHandler;
use Monolog\Level;
use Monolog\Logger;
use Monolog\LogRecord;
/**
* Monolog 2 -> 3, where the break is NOT where the guides put it.
*
* Measured against monolog 3 rather than assumed: Logger::WARNING and the
* other integer constants still exist and still equal the enum's ->value,
* and addRecord still accepts an int. So the "replace every constant" step
* is not what breaks an upgrade.
*
* What breaks is the handler side. A record is a LogRecord object now, not
* an array — and because LogRecord implements ArrayAccess, $record['message']
* keeps working. Code reading records looks fine and keeps passing until it
* reaches an is_array(), an array_key_exists() or an array function, which
* are the paths that silently stop matching.
*/
final class Records
{
/** @return array{0: LogRecord, 1: TestHandler} */
public static function capture(string $message, array $context = []): array
{
$handler = new TestHandler();
$logger = new Logger('csx', [$handler]);
$logger->warning($message, $context);
return [$handler->getRecords()[0], $handler];
}
public static function levelIntStillMatchesEnum(): bool
{
return Logger::WARNING === Level::Warning->value;
}
public static function addRecordStillAcceptsInt(): string
{
return (string) (new \ReflectionMethod(Logger::class, 'addRecord'))
->getParameters()[0]->getType();
}
}
<?php
use Csx\Records;
use Monolog\Level;
use Monolog\Logger;
use Monolog\LogRecord;
use PHPUnit\Framework\TestCase;
final class RecordsTest extends TestCase
{
public function testTheIntegerLevelConstantsWereNotRemoved(): void
{
// Measured, and the opposite of the usual advice: Logger::WARNING
// is still there on monolog 3 and still equals the enum's value.
$this->assertTrue(defined('Monolog' . chr(92) . 'Logger::WARNING'));
$this->assertSame(300, Logger::WARNING);
$this->assertSame(300, Level::Warning->value);
$this->assertTrue(Records::levelIntStillMatchesEnum());
$this->assertStringContainsString('int', Records::addRecordStillAcceptsInt());
}
public function testARecordIsAnObjectSoIsArrayStopsMatching(): void
{
[$record] = Records::capture('hello', ['k' => 'v']);
$this->assertInstanceOf(LogRecord::class, $record);
// The line that breaks an upgraded handler, and it breaks quietly:
// no error, the branch is simply never taken again.
$this->assertFalse(is_array($record));
}
public function testButArrayReadsKeepWorkingWhichIsWhyItLooksFine(): void
{
[$record] = Records::capture('hello', ['k' => 'v']);
$this->assertSame('hello', $record['message']);
$this->assertSame('hello', $record->message);
$this->assertSame(['k' => 'v'], $record->context);
$this->assertSame('WARNING', $record->level->getName());
}
public function testDatetimeIsADateTimeImmutableSubclass(): void
{
[$record] = Records::capture('hello');
$this->assertInstanceOf(DateTimeImmutable::class, $record->datetime);
$this->assertNotSame(DateTimeImmutable::class, get_class($record->datetime));
}
public function testTestHandlerAssertionsReadTheObjectForm(): void
{
[, $handler] = Records::capture('hello');
$this->assertTrue($handler->hasWarningThatContains('hello'));
$this->assertFalse($handler->hasErrorThatContains('hello'));
}
}