summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README.md72
-rw-r--r--composer.json31
-rw-r--r--composer.lock1651
-rw-r--r--src/Driver.php11
-rw-r--r--src/Drivers/FileSystemDriver.php53
-rw-r--r--src/Drivers/OutputDriver.php19
-rw-r--r--src/Format.php135
-rw-r--r--src/Level.php18
-rw-r--r--src/Loggr.php151
-rw-r--r--src/Message.php15
-rw-r--r--tests/Drivers/FileSystemDriverTest.php155
-rw-r--r--tests/Drivers/OutputDriverTest.php99
-rw-r--r--tests/LoggrTest.php31
14 files changed, 2443 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e0caea8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.idea/
+vendor/ \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0be05dd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+# Loggr
+
+An extendable logging utility class brought to you by the frustration of every logging class always having its own unique format,
+which makes using log viewing tools difficult. Instead of having its own yet-another-format that no tool supports, Loggr attempts to match
+many already existing formats, allowing you to use whichever you prefer most.
+
+## Requirements
+
+- PHP 8.3+
+
+## Installation
+
+```bash
+composer require asko/loggr
+```
+
+## Usage
+
+Loggr is very simple to use, and looks like this:
+
+```php
+$loggr = new Loggr(new FileSystemDriver('path-to-logs'));
+$loggr->info('context');
+```
+
+All you have to do is instantiate Loggr with the appropriate driver for your use case and then simply
+log away with any data you want to give it. It takes scalar values, as well as arrays and objects.
+
+### Methods
+
+Loggr supports all of these logging methods:
+
+- `emergency(mixed $context = null)`
+- `alert(mixed $context = null)`
+- `critical( mixed $context = null)`
+- `error(mixed $context = null)`
+- `warning(mixed $context = null)`
+- `notice(mixed $context = null)`
+- `info(mixed $context = null)`
+- `debug(mixed $context = null)`
+
+### Setting log format
+
+You can change the logging format by setting the `format` variable in Loggr constructor to a value of `Format` enum, like so:
+
+```php
+$loggr = new Loggr(new FileSystemDriver('path-to-logs'), format: Format::JSON);
+```
+
+Or, if that gets a bit too long for just one line, you can also do:
+
+```php
+$loggr = new Loggr(new FileSystemDriver('path-to-logs'));
+$loggr->format = Format::JSON;
+```
+
+Loggr supports the following log formats:
+
+- `Format::JSON` - Entries are JSON objects.
+- `Format::Laravel` - Entries correspond to the Laravel log format.
+- `Format::Symfony` - Entries correspond to the Symfony log format.
+- `Format::IntelliJ` - Entries correspond to the IntelliJ log format.
+
+## Extending
+
+You can extend Loggr with your own custom drivers. A driver is a class that implements the `Driver` interface and is
+responsible for making sure that the serialized log entry would end up in the right place.
+
+### Built-in drivers
+
+- [FileSystemDriver](#)
+- [StdoutDriver](#) \ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..4ee9199
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "asko/loggr",
+ "description": "An extendable logging utility class with built-in support for various logging formats.",
+ "type": "library",
+ "license": "MIT",
+ "autoload": {
+ "psr-4": {
+ "Asko\\Loggr\\": "src/"
+ },
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Asko\\Loggr\\Tests\\": "tests/"
+ }
+ },
+ "authors": [
+ {
+ "name": "Asko Nomm",
+ "email": "asko@faultd.com"
+ }
+ ],
+ "require": {
+ "php": "^8.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "11"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..b3438f6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1651 @@
+{
+ "_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": "a72050425367efbe00504e8bd2e37500",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.12.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
+ "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^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.12.1"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-11-08T17:47:46+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v5.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
+ "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "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.0-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.3.1"
+ },
+ "time": "2024-10-08T18:51:32+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": "11.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca",
+ "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^5.3.1",
+ "php": ">=8.2",
+ "phpunit/php-file-iterator": "^5.1.0",
+ "phpunit/php-text-template": "^4.0.1",
+ "sebastian/code-unit-reverse-lookup": "^4.0.1",
+ "sebastian/complexity": "^4.0.1",
+ "sebastian/environment": "^7.2.0",
+ "sebastian/lines-of-code": "^3.0.1",
+ "sebastian/version": "^5.0.2",
+ "theseer/tokenizer": "^1.2.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.4.1"
+ },
+ "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": "11.0.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/11.0.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-10-09T06:21:38+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6",
+ "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "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": "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/5.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-08-27T05:02:59+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "5.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2",
+ "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^11.0"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "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": "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/5.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:07:44+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
+ "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.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/4.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:08:43+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "7.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
+ "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.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": "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/7.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:09:35+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "11.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "ece3536c22fc5113906a42e7e82de00baaef36d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ece3536c22fc5113906a42e7e82de00baaef36d0",
+ "reference": "ece3536c22fc5113906a42e7e82de00baaef36d0",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.10.1",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=8.2",
+ "phpunit/php-code-coverage": "^11.0",
+ "phpunit/php-file-iterator": "^5.0",
+ "phpunit/php-invoker": "^5.0",
+ "phpunit/php-text-template": "^4.0",
+ "phpunit/php-timer": "^7.0",
+ "sebastian/cli-parser": "^3.0",
+ "sebastian/code-unit": "^3.0",
+ "sebastian/comparator": "^6.0",
+ "sebastian/diff": "^6.0",
+ "sebastian/environment": "^7.0",
+ "sebastian/exporter": "^6.0",
+ "sebastian/global-state": "^7.0",
+ "sebastian/object-enumerator": "^6.0",
+ "sebastian/type": "^5.0",
+ "sebastian/version": "^5.0"
+ },
+ "suggest": {
+ "ext-soap": "To be able to generate mocks based on WSDL files"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "11.0-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/11.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-02T06:12:57+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180",
+ "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.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/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:41:36+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "6bb7d09d6623567178cf54126afa9c2310114268"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268",
+ "reference": "6bb7d09d6623567178cf54126afa9c2310114268",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.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": "Collection of value objects that represent the PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "security": "https://github.com/sebastianbergmann/code-unit/security/policy",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:44:28+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "183a9b2632194febd219bb9246eee421dad8d45e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e",
+ "reference": "183a9b2632194febd219bb9246eee421dad8d45e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:45:54+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "6.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739",
+ "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-mbstring": "*",
+ "php": ">=8.2",
+ "sebastian/diff": "^6.0",
+ "sebastian/exporter": "^6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.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": "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/6.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-10-31T05:30:08+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "ee41d384ab1906c68852636b6de493846e13e5a0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0",
+ "reference": "ee41d384ab1906c68852636b6de493846e13e5a0",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.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/4.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:49:50+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "6.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544",
+ "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "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"
+ },
+ {
+ "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/6.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:53:05+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "7.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
+ "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "7.2-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/7.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:54:44+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
+ "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=8.2",
+ "sebastian/recursion-context": "^6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.1-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/6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:56:19+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "7.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "3be331570a721f9a4b5917f4209773de17f747d7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7",
+ "reference": "3be331570a721f9a4b5917f4209773de17f747d7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2",
+ "sebastian/object-reflector": "^4.0",
+ "sebastian/recursion-context": "^6.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^11.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"
+ }
+ ],
+ "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/7.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:57:36+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a",
+ "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.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/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:58:38+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "6.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "f5b498e631a74204185071eb41f33f38d64608aa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa",
+ "reference": "f5b498e631a74204185071eb41f33f38d64608aa",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2",
+ "sebastian/object-reflector": "^4.0",
+ "sebastian/recursion-context": "^6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.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": "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/6.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:00:13+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9",
+ "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "4.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/4.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:01:32+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "6.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "694d156164372abbd149a4b85ccda2e4670c0e16"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16",
+ "reference": "694d156164372abbd149a4b85ccda2e4670c0e16",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.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"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:10:34+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac",
+ "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.1-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": "Collection of value objects that represent the types of the PHP type system",
+ "homepage": "https://github.com/sebastianbergmann/type",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "security": "https://github.com/sebastianbergmann/type/security/policy",
+ "source": "https://github.com/sebastianbergmann/type/tree/5.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-09-17T13:12:04+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "5.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874",
+ "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "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 that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "security": "https://github.com/sebastianbergmann/version/security/policy",
+ "source": "https://github.com/sebastianbergmann/version/tree/5.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-10-09T05:16:32+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "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"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:36:25+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/src/Driver.php b/src/Driver.php
new file mode 100644
index 0000000..2bc6cb8
--- /dev/null
+++ b/src/Driver.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Asko\Loggr;
+
+/**
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+interface Driver
+{
+ public function log(string $serializedMessage): void;
+} \ No newline at end of file
diff --git a/src/Drivers/FileSystemDriver.php b/src/Drivers/FileSystemDriver.php
new file mode 100644
index 0000000..16c1461
--- /dev/null
+++ b/src/Drivers/FileSystemDriver.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Asko\Loggr\Drivers;
+
+use Asko\Loggr\Driver;
+use DateTime;
+
+/**
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+readonly class FileSystemDriver implements Driver
+{
+ public function __construct(
+ private string $directory,
+ ) {}
+
+ /**
+ * Logs a serialized message to a file. The log file is created on a daily basis.
+ * If the required directory or log file does not exist, they are created.
+ * Ensures that the log file is writable before attempting to write the message.
+ *
+ * @param string $serializedMessage The message to be logged, serialized as a string.
+ * @return void
+ * @throws \RuntimeException If the log file or directory cannot be created, or if the log file is not writable.
+ */
+ public function log(string $serializedMessage): void
+ {
+ // If there's no parent directory, try creating one
+ if (!is_dir($this->directory)) {
+ mkdir($this->directory, 0600, true);
+ }
+
+ $date = new DateTime();
+ $file_name = "{$date->format('Y-m-d')}.log";
+ $path = $this->directory . DIRECTORY_SEPARATOR . $file_name;
+
+ // If the log file does not exist, try creating one
+ if (!file_exists($path) && !touch($path)) {
+ throw new \RuntimeException('Log file could not be created');
+ }
+
+ // We managed to get this far, but still can't write to the log file
+ if (!is_writeable($path)) {
+ throw new \RuntimeException('Log file is not writeable');
+ }
+
+ file_put_contents(
+ filename: $path,
+ data: $serializedMessage . PHP_EOL,
+ flags: FILE_APPEND
+ );
+ }
+} \ No newline at end of file
diff --git a/src/Drivers/OutputDriver.php b/src/Drivers/OutputDriver.php
new file mode 100644
index 0000000..93c97ba
--- /dev/null
+++ b/src/Drivers/OutputDriver.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Asko\Loggr\Drivers;
+
+use Asko\Loggr\Driver;
+
+class OutputDriver implements Driver
+{
+ /**
+ * Writes the provided serialized message to the standard output stream.
+ *
+ * @param string $serializedMessage The message to be logged, in a serialized format.
+ * @return void
+ */
+ public function log(string $serializedMessage): void
+ {
+ file_put_contents('php://output', $serializedMessage);
+ }
+} \ No newline at end of file
diff --git a/src/Format.php b/src/Format.php
new file mode 100644
index 0000000..5f914b7
--- /dev/null
+++ b/src/Format.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Asko\Loggr;
+
+use DateTime;
+
+/**
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+enum Format
+{
+ case JSON;
+ case IntelliJ;
+ case Laravel;
+ case Symfony;
+
+ /**
+ * Serializes the given message into a format based on the type of serialization.
+ *
+ * @param Message $message The message to be serialized.
+ * @return string The serialized message.
+ */
+ public function serialize(Message $message): string
+ {
+ return match($this) {
+ self::JSON => $this->serializeJson($message),
+ self::IntelliJ => $this->serializeIntelliJ($message),
+ self::Laravel => $this->serializeLaravel($message),
+ self::Symfony => $this->serializeSymfony($message),
+ };
+ }
+
+ /**
+ * Serializes the given message into JSON format.
+ *
+ * @param Message $message The message to be serialized.
+ * @return string The JSON-encoded message.
+ */
+ private function serializeJson(Message $message): string
+ {
+ return json_encode([
+ 'date' => (new DateTime)->format('Y-m-d H:i:s'),
+ 'level' => $message->level->value,
+ 'context' => $message->context,
+ 'trace' => [
+ 'file' => $message->trace['file'],
+ 'line' => $message->trace['line'],
+ ],
+ ]);
+ }
+
+ /**
+ * Serializes the given message into a Laravel log format.
+ *
+ * @param Message $message The message to be serialized.
+ * @return string The serialized message.
+ */
+ private function serializeLaravel(Message $message): string
+ {
+ // Date
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $line = "[$date] ";
+
+ // File name and level
+ $filename = pathinfo($message->trace['file'], PATHINFO_FILENAME);
+ $line .= "{$filename}.{$message->level->value}: ";
+
+ // Context
+ if (is_array($message->context) || is_object($message->context)) {
+ $line .= json_encode($message->context);
+ } else {
+ $line .= $message->context;
+ }
+
+ return $line;
+ }
+
+ /**
+ * Serialized the given message into a Symfony log format.
+ *
+ * @param Message $message The message object that contains log details.
+ * @return string The formatted log string.
+ */
+ private function serializeSymfony(Message $message): string
+ {
+ // Date
+ $date = (new DateTime)->format('Y-m-d\TH:i:s.uP');
+ $line = "[$date] ";
+
+ // File name and level
+ $filename = pathinfo($message->trace['file'], PATHINFO_FILENAME);
+ $line .= "{$filename}.{$message->level->value}: ";
+
+ // Context
+ if (is_array($message->context) || is_object($message->context)) {
+ $line .= json_encode($message->context);
+ } else {
+ $line .= $message->context;
+ }
+
+ return $line;
+ }
+
+ /**
+ * Serializes the given message into a IntelliJ log format.
+ *
+ * @param Message $message The message object that contains log details.
+ * @return string The formatted log string.
+ */
+ private function serializeIntelliJ(Message $message): string
+ {
+ // Date
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $line = "{$date} ";
+
+ // Line number
+ $line .= "[{$message->trace['line']}] ";
+
+ // Level
+ $line .= "{$message->level->value} ";
+
+ // Filename
+ $filename = pathinfo($message->trace['file'], PATHINFO_FILENAME);
+ $line .= "- {$filename} - ";
+
+ // Context
+ if (is_array($message->context) || is_object($message->context)) {
+ $line .= json_encode($message->context);
+ } else {
+ $line .= $message->context;
+ }
+
+ return $line;
+ }
+}
diff --git a/src/Level.php b/src/Level.php
new file mode 100644
index 0000000..5e573bc
--- /dev/null
+++ b/src/Level.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Asko\Loggr;
+
+/**
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+enum Level: string
+{
+ case Emergency = "EMERGENCY";
+ case Alert = "ALERT";
+ case Critical = "CRITICAL";
+ case Error = "ERROR";
+ case Warning = "WARNING";
+ case Notice = "NOTICE";
+ case Info = "INFO";
+ case Debug = "DEBUG";
+}
diff --git a/src/Loggr.php b/src/Loggr.php
new file mode 100644
index 0000000..9b52f1d
--- /dev/null
+++ b/src/Loggr.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace Asko\Loggr;
+
+/**
+ * Loggr is an extendable logging utility class brought to you by the frustration of
+ * every logging class always having its own unique format, making debugging difficult.
+ *
+ * Instead of having its own yet-another-format that no tool supports, Loggr attempts to match
+ * many already existing formats, allowing you to use whichever you prefer most.
+ *
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+class Loggr
+{
+ private array $trace;
+
+ public function __construct(
+ public ?Driver $driver = null,
+ public ?Format $format = Format::Laravel,
+ ){}
+
+ /**
+ * Logs a message at a specified level with optional context.
+ *
+ * @param Level $level The severity level of the log message. Defaults to Level::Info.
+ * @param mixed $context Additional data or context to include with the log message. Optional.
+ * @return void
+ * @throws \Exception
+ */
+ private function log(Level $level = Level::Info, mixed $context = null): void
+ {
+ if (!$this->driver) {
+ throw new \Exception("No driver has been set.");
+ }
+
+ if (!$this->format) {
+ throw new \Exception("No format has been set.");
+ }
+
+ $this->driver->log($this->format->serialize(new Message(
+ level: $level,
+ trace: $this->trace,
+ context: $context,
+ )));
+ }
+
+ /**
+ * Logs an emergency level message with optional context.
+ *
+ * @param mixed $context Additional data or context to include with the emergency message. Optional.
+ * @return void
+ * @throws \Exception
+ */
+ public function emergency(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Emergency, $context);
+ }
+
+ /**
+ * Sends an alert-level log message with optional context.
+ *
+ * @param mixed $context Additional data or context to include with the log message. Optional.
+ * @return void
+ * @throws \Exception
+ */
+ public function alert(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Alert, $context);
+ }
+
+ /**
+ * Logs a critical level message with optional context.
+ *
+ * @param mixed $context Additional data or context to include with the log message. Optional.
+ * @return void
+ * @throws \Exception
+ */
+ public function critical( mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Critical, $context);
+ }
+
+ /**
+ * Logs an error message with optional context.
+ *
+ * @param mixed $context Additional data or context to include with the error message. Optional.
+ * @return void
+ * @throws \Exception
+ */
+ public function error(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Error, $context);
+ }
+
+ /**
+ * Logs a warning message with the specified context.
+ *
+ * @param mixed $context Optional context information to include in the log.
+ * @return void
+ * @throws \Exception
+ */
+ public function warning(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Warning, $context);
+ }
+
+ /**
+ * Logs a notice message with the specified context.
+ *
+ * @param mixed $context Optional context information to include in the log.
+ * @return void
+ * @throws \Exception
+ */
+ public function notice(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Notice, $context);
+ }
+
+ /**
+ * Logs an informational message with the specified context.
+ *
+ * @param mixed $context Optional context information to include in the log.
+ * @return void
+ * @throws \Exception
+ */
+ public function info(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Info, $context);
+ }
+
+ /**
+ * Logs a debug message with the specified context.
+ *
+ * @param mixed $context Optional context information to include in the log.
+ * @return void
+ * @throws \Exception
+ */
+ public function debug(mixed $context = null): void
+ {
+ $this->trace = debug_backtrace()[0];
+ $this->log(Level::Debug, $context);
+ }
+} \ No newline at end of file
diff --git a/src/Message.php b/src/Message.php
new file mode 100644
index 0000000..4af49e7
--- /dev/null
+++ b/src/Message.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Asko\Loggr;
+
+/**
+ * @author Asko Nõmm <asko@faultd.com>
+ */
+readonly class Message
+{
+ public function __construct(
+ public Level $level,
+ public array $trace = [],
+ public mixed $context = null,
+ ) {}
+} \ No newline at end of file
diff --git a/tests/Drivers/FileSystemDriverTest.php b/tests/Drivers/FileSystemDriverTest.php
new file mode 100644
index 0000000..bb49042
--- /dev/null
+++ b/tests/Drivers/FileSystemDriverTest.php
@@ -0,0 +1,155 @@
+<?php
+
+namespace Asko\Loggr\Tests\Drivers;
+
+use Asko\Loggr\Drivers\FileSystemDriver;
+use Asko\Loggr\Loggr;
+use DateTime;
+use PHPUnit\Framework\TestCase;
+
+class FileSystemDriverTest extends TestCase
+{
+ /**
+ * @throws \Exception
+ */
+ public function testEmergency(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->emergency('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.EMERGENCY: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testAlert(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->alert('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.ALERT: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testCritical(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->critical('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.CRITICAL: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testError(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->error('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.ERROR: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testWarning(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->warning('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.WARNING: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testNotice(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->notice('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.NOTICE: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testInfo(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->info('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.INFO: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testDebug(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->debug('test');
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.DEBUG: test", $last_line);
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testMultipleEntries(): void
+ {
+ $date = new DateTime();
+ $loggr = new Loggr(new FileSystemDriver(__DIR__ . '/logs'));
+ $loggr->emergency('test');
+ $loggr->alert('test');
+ $loggr->critical('test');
+ $loggr->error('test');
+ $loggr->warning('test');
+ $loggr->notice('test');
+ $loggr->info('test');
+ $loggr->debug('test');
+
+ $lines = file(__DIR__ . '/logs/' . $date->format('Y-m-d') . '.log');
+ $this->assertCount(8, $lines);
+
+ $first_line = $lines[0];
+ $last_line = end($lines);
+ $full_date = $date->format('Y-m-d H:i:s');
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.EMERGENCY: test", $first_line);
+ $this->assertStringContainsString("[{$full_date}] FileSystemDriverTest.DEBUG: test", $last_line);
+ }
+
+ public function tearDown(): void
+ {
+ array_map('unlink', glob(__DIR__ . '/logs/*'));
+ rmdir(__DIR__ . '/logs');
+ }
+} \ No newline at end of file
diff --git a/tests/Drivers/OutputDriverTest.php b/tests/Drivers/OutputDriverTest.php
new file mode 100644
index 0000000..9f023ae
--- /dev/null
+++ b/tests/Drivers/OutputDriverTest.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Asko\Loggr\Tests\Drivers;
+
+use Asko\Loggr\Drivers\OutputDriver;
+use Asko\Loggr\Loggr;
+use DateTime;
+use PHPUnit\Framework\TestCase;
+
+class OutputDriverTest extends TestCase
+{
+ /**
+ * @throws \Exception
+ */
+ public function testEmergency(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.EMERGENCY: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->emergency('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testAlert(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.ALERT: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->alert('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testCritical(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.CRITICAL: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->critical('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testError(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.ERROR: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->error('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testWarning(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.WARNING: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->warning('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testNotice(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.NOTICE: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->notice('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testInfo(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.INFO: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->info('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testDebug(): void
+ {
+ $date = (new DateTime)->format('Y-m-d H:i:s');
+ $this->expectOutputString("[{$date}] OutputDriverTest.DEBUG: test");
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->debug('test');
+ }
+} \ No newline at end of file
diff --git a/tests/LoggrTest.php b/tests/LoggrTest.php
new file mode 100644
index 0000000..4abae86
--- /dev/null
+++ b/tests/LoggrTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Asko\Loggr\Tests;
+
+use Asko\Loggr\Drivers\OutputDriver;
+use Asko\Loggr\Loggr;
+use PHPUnit\Framework\TestCase;
+
+class LoggrTest extends TestCase
+{
+ /**
+ * @throws \Exception
+ */
+ public function testNoDriver(): void
+ {
+ $this->expectExceptionMessage('No driver has been set.');
+ $loggr = new Loggr();
+ $loggr->info('test');
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public function testNoFormat(): void
+ {
+ $this->expectExceptionMessage('No format has been set.');
+ $loggr = new Loggr(new OutputDriver());
+ $loggr->format = null;
+ $loggr->info('test');
+ }
+} \ No newline at end of file