diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..8a60024
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,71 @@
+name: Build
+
+on:
+ pull_request:
+ branches:
+ - '*'
+ push:
+ branches:
+ - 'master'
+
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ platform-reqs:
+ - use-platform-reqs
+ php-version:
+ - "8.1"
+ - "8.2"
+ - "8.3"
+ dependencies:
+ - lowest
+ - highest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+
+ - name: Install PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+
+ - name: Install PHIVE
+ uses: szepeviktor/phive@v1
+
+ - name: Install lowest dependencies
+ if: ${{ matrix.dependencies == 'lowest' && matrix.platform-reqs == 'use-platform-reqs' }}
+ run: composer update --no-interaction --prefer-lowest
+
+ - name: Install lowest dependencies (ignore platform reqs)
+ if: ${{ matrix.dependencies == 'lowest' && matrix.platform-reqs == 'ignore-platform-reqs' }}
+ run: composer update --no-interaction --prefer-lowest --ignore-platform-reqs
+
+ - name: Install highest dependencies
+ if: ${{ matrix.dependencies == 'highest' && matrix.platform-reqs == 'use-platform-reqs' }}
+ run: composer update --no-interaction
+
+ - name: Install highest dependencies (ignore platform reqs)
+ if: ${{ matrix.dependencies == 'highest' && matrix.platform-reqs == 'ignore-platform-reqs' }}
+ run: composer update --no-interaction --ignore-platform-reqs
+
+ - name: Run tests
+ run: composer test
+
+ - name: Run infection
+ run: composer infection
+ env:
+ STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
+
+ - name: Upload coverage to Codecov.io
+ run: bash <(curl -s https://codecov.io/bash -s "build/logs")
+ continue-on-error: true
+
+ - name: Upload coverage to Scrutinizer
+ uses: sudo-bot/action-scrutinizer@latest
+ with:
+ cli-args: --format=php-clover build/logs/clover.xml
+ continue-on-error: true
diff --git a/.gitignore b/.gitignore
index 04d9ea3..6958379 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
/build/
/vendor/
/composer.lock
+/vendor-bin/**/vendor/
+/vendor-bin/**/composer.lock
/infection.json
/phpunit.xml
+/tools/
.phpunit.result.cache
diff --git a/.phive/phars.xml b/.phive/phars.xml
new file mode 100644
index 0000000..bda539d
--- /dev/null
+++ b/.phive/phars.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 47ac2e3..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-language: php
-
-env:
- global:
- - XDEBUG=YES
- - XDEBUG_MODE=coverage
-
-matrix:
- include:
- - php: '7.3'
- - php: '7.4'
- - php: '8.0'
-
-install:
- - mkdir -p ./build/logs
- - composer self-update
- - composer install --prefer-source --no-interaction
-
-script:
- - vendor/bin/phpcs -sp --report-junit=build/logs/phpcs.xml
- - if [ "$XDEBUG" == "YES" ]; then vendor/bin/phpunit --coverage-clover=build/logs/clover.xml --coverage-xml=build/logs/coverage-xml --log-junit=build/logs/junit.xml; else vendor/bin/phpunit; fi
- - if [ "$XDEBUG" == "YES" ]; then vendor/bin/infection --coverage=build/logs --threads=4 --no-progress --skip-initial-tests; fi
-
-after_success:
- - if [ "$XDEBUG" == "YES" ]; then bash <(curl -s https://codecov.io/bash -s "build/logs"); fi
- - if [ "$XDEBUG" == "YES" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi
- - if [ "$XDEBUG" == "YES" ]; then php ocular.phar code-coverage:upload --access-token=$SCRUTINIZER_TOKEN --format=php-clover build/logs/clover.xml; fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1e4a84..b76120a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.7.0] - 2024-02-17
+### Added
+- Cloning setters added to events to make stream modification easier.
+
+## [0.6.1] - 2024-02-11
+### Added
+- Added PHP 8.3 support.
+### Removed
+- Removed PHP 8.0 support.
+
+## [0.6.0] - 2023-06-16
+### Changed
+- JSON source structure may contain arbitrary objects, not only `stdClass`.
+### Removed
+- Dropped PHP 7 support.
+
## [0.5.3] - 2021-01-14
### Added
- PHP 8.0 support.
diff --git a/LICENSE b/LICENSE
index f7a5ce0..9e9e88a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2016-2019 Edward Surov
+Copyright (c) 2016-2024 Edward Surov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index ad3d9fd..413bd30 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,14 @@
[](https://scrutinizer-ci.com/g/remorhaz/php-json-data/?branch=master)
[](https://codecov.io/gh/remorhaz/php-json-data)
[](https://packagist.org/packages/remorhaz/php-json-data)
-[](https://stryker-mutator.github.io)
+[](https://dashboard.stryker-mutator.io/reports/github.com/remorhaz/php-json-data/master)
[](https://packagist.org/packages/remorhaz/php-json-data)
This library provides infrastructure for JSON documents processing.
## Requirements
-- PHP 7.3+
+- PHP 8.1 or newer.
- [Internationalization functions](https://www.php.net/manual/en/book.intl.php) (ext-intl) - to compare Unicode strings.
- [JSON extension](https://www.php.net/manual/en/book.json.php) (ext-json) - to encode and decode JSON documents.
diff --git a/composer.json b/composer.json
index 0190d6d..254303b 100644
--- a/composer.json
+++ b/composer.json
@@ -14,14 +14,13 @@
}
],
"require": {
- "php": "^7.3 | ^8",
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"ext-json": "*",
"ext-intl": "*"
},
"require-dev": {
- "phpunit/phpunit": "^9.5",
- "squizlabs/php_codesniffer": "^3.5",
- "infection/infection": "^0.18"
+ "bamarni/composer-bin-plugin": "^1.8",
+ "phpunit/phpunit": "^10.1 || ^11"
},
"autoload": {
"psr-4": {
@@ -30,24 +29,46 @@
},
"autoload-dev": {
"psr-4": {
- "Remorhaz\\JSON\\Test\\Data\\": "tests/"
+ "Remorhaz\\JSON\\Data\\Test\\": "tests/"
}
},
"scripts": {
+ "post-update-cmd": ["@phive-install"],
+ "post-install-cmd": ["@phive-install"],
+ "phive-install": [
+ "`if [ -f tools/phive ]; then echo 'tools/'; fi`phive install --trust-gpg-keys C5095986493B4AA0"
+ ],
"test-cs": [
- "vendor/bin/phpcs -sp"
+ "vendor-bin/cs/vendor/bin/phpcs -sp"
],
"test-unit": [
- "vendor/bin/phpunit --coverage-xml=build/log/coverage-xml --log-junit=build/log/junit.xml"
+ "vendor/bin/phpunit --coverage-xml=build/log/coverage-xml --coverage-clover=build/log/clover.xml --log-junit=build/log/junit.xml"
],
+ "test-psalm": "vendor-bin/psalm/vendor/bin/psalm --threads=4 --shepherd",
"test": [
- "@test-sp",
- "@test-unit"
+ "@test-cs",
+ "@test-unit",
+ "@test-psalm"
],
"infection": [
- "@test-unit",
"mkdir -p build/log/infection",
- "vendor/bin/infection --threads=4 --coverage=build/log --no-progress --skip-initial-tests"
+ "tools/infection --threads=4 --coverage=build/log --no-progress --skip-initial-tests"
+ ],
+ "test-infection": [
+ "@test-unit",
+ "@infection"
]
+ },
+ "config": {
+ "allow-plugins": {
+ "bamarni/composer-bin-plugin": true
+ },
+ "sort-packages": true
+ },
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": false,
+ "forward-command": true
+ }
}
}
diff --git a/docker-compose.yml b/docker-compose.yml
index fe68e84..a3e8597 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,21 +4,21 @@ services:
php:
build:
context: .
- dockerfile: php-7.3.Dockerfile
+ dockerfile: php-8.1.Dockerfile
volumes:
- .:/app
working_dir: /app
- php7.4:
+ php8.2:
build:
context: .
- dockerfile: php-7.4.Dockerfile
+ dockerfile: php-8.2.Dockerfile
volumes:
- .:/app
working_dir: /app
- php8.0:
+ php8.3:
build:
context: .
- dockerfile: php-8.0.Dockerfile
+ dockerfile: php-8.3.Dockerfile
volumes:
- .:/app
working_dir: /app
diff --git a/infection.json.dist b/infection.json.dist
index b9398ec..ab00190 100644
--- a/infection.json.dist
+++ b/infection.json.dist
@@ -9,8 +9,9 @@
"text": "build/logs/infection/infection.log",
"summary": "build/logs/infection/summary.log",
"perMutator": "build/logs/infection/per-mutator.md",
- "badge": {
- "branch": "master"
+ "github": true,
+ "stryker": {
+ "badge": "/^master$/"
}
}
}
\ No newline at end of file
diff --git a/php-7.3.Dockerfile b/php-7.3.Dockerfile
deleted file mode 100644
index d0837cb..0000000
--- a/php-7.3.Dockerfile
+++ /dev/null
@@ -1,17 +0,0 @@
-FROM php:7.3-cli
-
-RUN apt-get update && apt-get install -y \
- zip \
- git \
- libicu-dev && \
- pecl install xdebug && \
- docker-php-ext-enable xdebug && \
- docker-php-ext-configure intl --enable-intl && \
- docker-php-ext-install intl && \
- echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
-
-ENV COMPOSER_ALLOW_SUPERUSER=1 \
- COMPOSER_PROCESS_TIMEOUT=1200
-
-RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
- --install-dir=/usr/bin --filename=composer
diff --git a/php-7.4.Dockerfile b/php-7.4.Dockerfile
deleted file mode 100644
index 5d769fa..0000000
--- a/php-7.4.Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM php:7.4-cli
-
-RUN apt-get update && apt-get install -y \
- zip \
- git \
- libicu-dev && \
- docker-php-ext-configure intl --enable-intl && \
- docker-php-ext-install intl && \
- echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
-
-ENV COMPOSER_ALLOW_SUPERUSER=1 \
- COMPOSER_PROCESS_TIMEOUT=1200
-
-RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
- --install-dir=/usr/bin --filename=composer
diff --git a/php-8.0.Dockerfile b/php-8.0.Dockerfile
deleted file mode 100644
index 8dc4ed3..0000000
--- a/php-8.0.Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM php:8.0-cli
-
-RUN apt-get update && apt-get install -y \
- zip \
- git \
- libicu-dev && \
- docker-php-ext-configure intl --enable-intl && \
- docker-php-ext-install intl && \
- echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
-
-ENV COMPOSER_ALLOW_SUPERUSER=1 \
- COMPOSER_PROCESS_TIMEOUT=1200
-
-RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
- --install-dir=/usr/bin --filename=composer
diff --git a/php-8.1.Dockerfile b/php-8.1.Dockerfile
new file mode 100644
index 0000000..5df62cd
--- /dev/null
+++ b/php-8.1.Dockerfile
@@ -0,0 +1,27 @@
+FROM php:8.1-cli
+
+RUN apt-get update && apt-get install -y \
+ zip \
+ git \
+ wget \
+ gpg \
+ libicu-dev && \
+ pecl install xdebug && \
+ docker-php-ext-enable xdebug && \
+ docker-php-ext-configure intl --enable-intl && \
+ docker-php-ext-install intl pcntl && \
+ echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
+
+ENV COMPOSER_ALLOW_SUPERUSER=1 \
+ COMPOSER_PROCESS_TIMEOUT=1200
+
+RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
+ --install-dir=/usr/bin --filename=composer && \
+ git config --global --add safe.directory "*"
+
+RUN wget -O phive.phar https://phar.io/releases/phive.phar && \
+ wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \
+ gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \
+ gpg --verify phive.phar.asc phive.phar && \
+ chmod +x phive.phar && \
+ mv phive.phar /usr/local/bin/phive \
diff --git a/php-8.2.Dockerfile b/php-8.2.Dockerfile
new file mode 100644
index 0000000..5794eeb
--- /dev/null
+++ b/php-8.2.Dockerfile
@@ -0,0 +1,27 @@
+FROM php:8.2-cli
+
+RUN apt-get update && apt-get install -y \
+ zip \
+ git \
+ wget \
+ gpg \
+ libicu-dev && \
+ pecl install xdebug && \
+ docker-php-ext-enable xdebug && \
+ docker-php-ext-configure intl --enable-intl && \
+ docker-php-ext-install intl pcntl && \
+ echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
+
+ENV COMPOSER_ALLOW_SUPERUSER=1 \
+ COMPOSER_PROCESS_TIMEOUT=1200
+
+RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
+ --install-dir=/usr/bin --filename=composer && \
+ git config --global --add safe.directory "*"
+
+RUN wget -O phive.phar https://phar.io/releases/phive.phar && \
+ wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \
+ gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \
+ gpg --verify phive.phar.asc phive.phar && \
+ chmod +x phive.phar && \
+ mv phive.phar /usr/local/bin/phive \
diff --git a/php-8.3.Dockerfile b/php-8.3.Dockerfile
new file mode 100644
index 0000000..6a6bc0d
--- /dev/null
+++ b/php-8.3.Dockerfile
@@ -0,0 +1,27 @@
+FROM php:8.3-cli
+
+RUN apt-get update && apt-get install -y \
+ zip \
+ git \
+ wget \
+ gpg \
+ libicu-dev && \
+ pecl install xdebug && \
+ docker-php-ext-enable xdebug && \
+ docker-php-ext-configure intl --enable-intl && \
+ docker-php-ext-install intl pcntl && \
+ echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini"
+
+ENV COMPOSER_ALLOW_SUPERUSER=1 \
+ COMPOSER_PROCESS_TIMEOUT=1200
+
+RUN curl --silent --show-error https://getcomposer.org/installer | php -- \
+ --install-dir=/usr/bin --filename=composer && \
+ git config --global --add safe.directory "*"
+
+RUN wget -O phive.phar https://phar.io/releases/phive.phar && \
+ wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \
+ gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \
+ gpg --verify phive.phar.asc phive.phar && \
+ chmod +x phive.phar && \
+ mv phive.phar /usr/local/bin/phive \
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index f9a7b24..df2a9ff 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,18 +1,19 @@
-
+
-
-
- tests/
-
-
-
-
- src/
-
-
+ colors="true"
+ cacheDirectory="build/.phpunit.cache"
+ requireCoverageMetadata="true">
+
+
+ tests/
+
+
+
+
+ src/
+
+
diff --git a/psalm.xml.dist b/psalm.xml.dist
new file mode 100644
index 0000000..efca3b8
--- /dev/null
+++ b/psalm.xml.dist
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Comparator/ComparatorInterface.php b/src/Comparator/ComparatorInterface.php
index c285afc..5810d64 100644
--- a/src/Comparator/ComparatorInterface.php
+++ b/src/Comparator/ComparatorInterface.php
@@ -8,6 +8,5 @@
interface ComparatorInterface
{
-
public function compare(ValueInterface $leftValue, ValueInterface $rightValue): bool;
}
diff --git a/src/Comparator/ContainsValueComparator.php b/src/Comparator/ContainsValueComparator.php
index acc5b1a..c235f70 100644
--- a/src/Comparator/ContainsValueComparator.php
+++ b/src/Comparator/ContainsValueComparator.php
@@ -7,14 +7,14 @@
use Collator;
use Iterator;
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
+use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Remorhaz\JSON\Data\Value\ObjectValueInterface;
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
use Remorhaz\JSON\Data\Value\ValueInterface;
final class ContainsValueComparator implements ComparatorInterface
{
-
- private $equalComparator;
+ private EqualValueComparator $equalComparator;
public function __construct(Collator $collator)
{
@@ -23,17 +23,14 @@ public function __construct(Collator $collator)
public function compare(ValueInterface $leftValue, ValueInterface $rightValue): bool
{
- if ($leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface) {
- return $this->equalComparator->compare($leftValue, $rightValue);
- }
- if ($leftValue instanceof ArrayValueInterface && $rightValue instanceof ArrayValueInterface) {
- return $this->equalComparator->compare($leftValue, $rightValue);
- }
- if ($leftValue instanceof ObjectValueInterface && $rightValue instanceof ObjectValueInterface) {
- return $this->objectContains($leftValue, $rightValue);
- }
-
- return false;
+ return match (true) {
+ $leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface,
+ $leftValue instanceof ArrayValueInterface && $rightValue instanceof ArrayValueInterface =>
+ $this->equalComparator->compare($leftValue, $rightValue),
+ $leftValue instanceof ObjectValueInterface && $rightValue instanceof ObjectValueInterface =>
+ $this->objectContains($leftValue, $rightValue),
+ default => false,
+ };
}
private function objectContains(ObjectValueInterface $leftValue, ObjectValueInterface $rightValue): bool
@@ -58,6 +55,10 @@ private function objectContains(ObjectValueInterface $leftValue, ObjectValueInte
return true;
}
+ /**
+ * @param Iterator $valueIterator
+ * @return null|array
+ */
private function getPropertiesWithoutDuplicates(Iterator $valueIterator): ?array
{
$valuesByProperty = [];
diff --git a/src/Comparator/EqualValueComparator.php b/src/Comparator/EqualValueComparator.php
index 850fbe6..aa7f1e4 100644
--- a/src/Comparator/EqualValueComparator.php
+++ b/src/Comparator/EqualValueComparator.php
@@ -7,6 +7,7 @@
use Collator;
use Iterator;
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
+use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Remorhaz\JSON\Data\Value\ObjectValueInterface;
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
use Remorhaz\JSON\Data\Value\ValueInterface;
@@ -15,29 +16,22 @@
final class EqualValueComparator implements ComparatorInterface
{
-
- private $collator;
-
- public function __construct(Collator $collator)
- {
- $this->collator = $collator;
+ public function __construct(
+ private readonly Collator $collator,
+ ) {
}
public function compare(ValueInterface $leftValue, ValueInterface $rightValue): bool
{
- if ($leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface) {
- return $this->isScalarEqual($leftValue, $rightValue);
- }
-
- if ($leftValue instanceof ArrayValueInterface && $rightValue instanceof ArrayValueInterface) {
- return $this->isArrayEqual($leftValue, $rightValue);
- }
-
- if ($leftValue instanceof ObjectValueInterface && $rightValue instanceof ObjectValueInterface) {
- return $this->isObjectEqual($leftValue, $rightValue);
- }
-
- return false;
+ return match (true) {
+ $leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface =>
+ $this->isScalarEqual($leftValue, $rightValue),
+ $leftValue instanceof ArrayValueInterface && $rightValue instanceof ArrayValueInterface =>
+ $this->isArrayEqual($leftValue, $rightValue),
+ $leftValue instanceof ObjectValueInterface && $rightValue instanceof ObjectValueInterface =>
+ $this->isObjectEqual($leftValue, $rightValue),
+ default => false,
+ };
}
private function isScalarEqual(ScalarValueInterface $leftValue, ScalarValueInterface $rightValue): bool
@@ -45,11 +39,9 @@ private function isScalarEqual(ScalarValueInterface $leftValue, ScalarValueInter
$leftData = $leftValue->getData();
$rightData = $rightValue->getData();
- if (is_string($leftData) && is_string($rightData)) {
- return 0 === $this->collator->compare($leftData, $rightData);
- }
-
- return $leftData === $rightData;
+ return is_string($leftData) && is_string($rightData)
+ ? 0 === $this->collator->compare($leftData, $rightData)
+ : $leftData === $rightData;
}
private function isArrayEqual(ArrayValueInterface $leftValue, ArrayValueInterface $rightValue): bool
@@ -94,6 +86,10 @@ private function isObjectEqual(ObjectValueInterface $leftValue, ObjectValueInter
return empty($leftProperties);
}
+ /**
+ * @param Iterator $valueIterator
+ * @return null|array
+ */
private function getPropertiesWithoutDuplicates(Iterator $valueIterator): ?array
{
$valuesByProperty = [];
diff --git a/src/Comparator/GreaterValueComparator.php b/src/Comparator/GreaterValueComparator.php
index e24f50f..02dc616 100644
--- a/src/Comparator/GreaterValueComparator.php
+++ b/src/Comparator/GreaterValueComparator.php
@@ -14,21 +14,17 @@
final class GreaterValueComparator implements ComparatorInterface
{
-
- private $collator;
-
- public function __construct(Collator $collator)
- {
- $this->collator = $collator;
+ public function __construct(
+ private readonly Collator $collator,
+ ) {
}
public function compare(ValueInterface $leftValue, ValueInterface $rightValue): bool
{
- if ($leftValue instanceof ScalarValueInterface && $rightValue instanceof ScalarValueInterface) {
- return $this->isScalarGreater($leftValue, $rightValue);
- }
-
- return false;
+ return
+ $leftValue instanceof ScalarValueInterface &&
+ $rightValue instanceof ScalarValueInterface &&
+ $this->isScalarGreater($leftValue, $rightValue);
}
private function isScalarGreater(ScalarValueInterface $leftValue, ScalarValueInterface $rightValue): bool
@@ -39,10 +35,6 @@ private function isScalarGreater(ScalarValueInterface $leftValue, ScalarValueInt
return $leftData > $rightData;
}
- if (is_string($leftData) && is_string($rightData)) {
- return 1 === $this->collator->compare($leftData, $rightData);
- }
-
- return false;
+ return is_string($leftData) && is_string($rightData) && 1 === $this->collator->compare($leftData, $rightData);
}
}
diff --git a/src/Event/AfterArrayEvent.php b/src/Event/AfterArrayEvent.php
index 37aef89..ae8b627 100644
--- a/src/Event/AfterArrayEvent.php
+++ b/src/Event/AfterArrayEvent.php
@@ -8,16 +8,20 @@
final class AfterArrayEvent implements AfterArrayEventInterface
{
-
- private $path;
-
- public function __construct(PathInterface $path)
- {
- $this->path = $path;
+ public function __construct(
+ private readonly PathInterface $path,
+ ) {
}
public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null): AfterArrayEventInterface
+ {
+ return new self(
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/AfterArrayEventInterface.php b/src/Event/AfterArrayEventInterface.php
index e2b12ed..aeda584 100644
--- a/src/Event/AfterArrayEventInterface.php
+++ b/src/Event/AfterArrayEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface AfterArrayEventInterface extends EventInterface
{
+ public function with(?PathInterface $path = null): AfterArrayEventInterface;
}
diff --git a/src/Event/AfterElementEvent.php b/src/Event/AfterElementEvent.php
index f5e1a7c..ee5eed1 100644
--- a/src/Event/AfterElementEvent.php
+++ b/src/Event/AfterElementEvent.php
@@ -8,15 +8,10 @@
final class AfterElementEvent implements AfterElementEventInterface
{
-
- private $index;
-
- private $path;
-
- public function __construct(int $index, PathInterface $path)
- {
- $this->index = $index;
- $this->path = $path;
+ public function __construct(
+ private readonly int $index,
+ private readonly PathInterface $path,
+ ) {
}
public function getPath(): PathInterface
@@ -28,4 +23,12 @@ public function getIndex(): int
{
return $this->index;
}
+
+ public function with(?PathInterface $path = null, ?int $index = null): AfterElementEventInterface
+ {
+ return new self(
+ index: $index ?? $this->index,
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/AfterElementEventInterface.php b/src/Event/AfterElementEventInterface.php
index 73b1a6d..e131250 100644
--- a/src/Event/AfterElementEventInterface.php
+++ b/src/Event/AfterElementEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface AfterElementEventInterface extends ElementEventInterface
{
+ public function with(?PathInterface $path = null, ?int $index = null,): AfterElementEventInterface;
}
diff --git a/src/Event/AfterObjectEvent.php b/src/Event/AfterObjectEvent.php
index dba4afa..965b099 100644
--- a/src/Event/AfterObjectEvent.php
+++ b/src/Event/AfterObjectEvent.php
@@ -8,16 +8,20 @@
final class AfterObjectEvent implements AfterObjectEventInterface
{
-
- private $path;
-
- public function __construct(PathInterface $path)
- {
- $this->path = $path;
+ public function __construct(
+ private readonly PathInterface $path,
+ ) {
}
public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null): AfterObjectEventInterface
+ {
+ return new self(
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/AfterObjectEventInterface.php b/src/Event/AfterObjectEventInterface.php
index bff27f1..f0b6964 100644
--- a/src/Event/AfterObjectEventInterface.php
+++ b/src/Event/AfterObjectEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface AfterObjectEventInterface extends EventInterface
{
+ public function with(?PathInterface $path = null): AfterObjectEventInterface;
}
diff --git a/src/Event/AfterPropertyEvent.php b/src/Event/AfterPropertyEvent.php
index e5ddb06..6d1526d 100644
--- a/src/Event/AfterPropertyEvent.php
+++ b/src/Event/AfterPropertyEvent.php
@@ -8,15 +8,10 @@
final class AfterPropertyEvent implements AfterPropertyEventInterface
{
-
- private $name;
-
- private $path;
-
- public function __construct(string $name, PathInterface $path)
- {
- $this->name = $name;
- $this->path = $path;
+ public function __construct(
+ private readonly string $name,
+ private readonly PathInterface $path,
+ ) {
}
public function getName(): string
@@ -28,4 +23,12 @@ public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null, ?string $name = null): AfterPropertyEventInterface
+ {
+ return new self(
+ name: $name ?? $this->name,
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/AfterPropertyEventInterface.php b/src/Event/AfterPropertyEventInterface.php
index a022948..e8b6eb6 100644
--- a/src/Event/AfterPropertyEventInterface.php
+++ b/src/Event/AfterPropertyEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface AfterPropertyEventInterface extends PropertyEventInterface
{
+ public function with(?PathInterface $path = null, ?string $name = null): AfterPropertyEventInterface;
}
diff --git a/src/Event/BeforeArrayEvent.php b/src/Event/BeforeArrayEvent.php
index 846620e..cc723e9 100644
--- a/src/Event/BeforeArrayEvent.php
+++ b/src/Event/BeforeArrayEvent.php
@@ -8,16 +8,20 @@
final class BeforeArrayEvent implements BeforeArrayEventInterface
{
-
- private $path;
-
- public function __construct(PathInterface $path)
- {
- $this->path = $path;
+ public function __construct(
+ private readonly PathInterface $path,
+ ) {
}
public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null): BeforeArrayEventInterface
+ {
+ return new self(
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/BeforeArrayEventInterface.php b/src/Event/BeforeArrayEventInterface.php
index dd32c4c..8ee5700 100644
--- a/src/Event/BeforeArrayEventInterface.php
+++ b/src/Event/BeforeArrayEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface BeforeArrayEventInterface extends EventInterface
{
+ public function with(?PathInterface $path = null): BeforeArrayEventInterface;
}
diff --git a/src/Event/BeforeElementEvent.php b/src/Event/BeforeElementEvent.php
index f7bb7df..bc4e53a 100644
--- a/src/Event/BeforeElementEvent.php
+++ b/src/Event/BeforeElementEvent.php
@@ -8,15 +8,10 @@
final class BeforeElementEvent implements BeforeElementEventInterface
{
-
- private $index;
-
- private $path;
-
- public function __construct(int $index, PathInterface $path)
- {
- $this->index = $index;
- $this->path = $path;
+ public function __construct(
+ private readonly int $index,
+ private readonly PathInterface $path,
+ ) {
}
public function getIndex(): int
@@ -24,9 +19,16 @@ public function getIndex(): int
return $this->index;
}
-
public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null, ?int $index = null): BeforeElementEventInterface
+ {
+ return new self(
+ index: $index ?? $this->index,
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/BeforeElementEventInterface.php b/src/Event/BeforeElementEventInterface.php
index 86328ba..eb634fc 100644
--- a/src/Event/BeforeElementEventInterface.php
+++ b/src/Event/BeforeElementEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface BeforeElementEventInterface extends ElementEventInterface
{
+ public function with(?PathInterface $path = null, ?int $index = null,): BeforeElementEventInterface;
}
diff --git a/src/Event/BeforeObjectEvent.php b/src/Event/BeforeObjectEvent.php
index 61b3d2b..a0f86ac 100644
--- a/src/Event/BeforeObjectEvent.php
+++ b/src/Event/BeforeObjectEvent.php
@@ -8,16 +8,20 @@
final class BeforeObjectEvent implements BeforeObjectEventInterface
{
-
- private $path;
-
- public function __construct(PathInterface $path)
- {
- $this->path = $path;
+ public function __construct(
+ private readonly PathInterface $path,
+ ) {
}
public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null): BeforeObjectEventInterface
+ {
+ return new self(
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/BeforeObjectEventInterface.php b/src/Event/BeforeObjectEventInterface.php
index 5f5cc7c..3d3b24d 100644
--- a/src/Event/BeforeObjectEventInterface.php
+++ b/src/Event/BeforeObjectEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface BeforeObjectEventInterface extends EventInterface
{
+ public function with(?PathInterface $path = null): BeforeObjectEventInterface;
}
diff --git a/src/Event/BeforePropertyEvent.php b/src/Event/BeforePropertyEvent.php
index c805799..987896f 100644
--- a/src/Event/BeforePropertyEvent.php
+++ b/src/Event/BeforePropertyEvent.php
@@ -8,15 +8,10 @@
final class BeforePropertyEvent implements BeforePropertyEventInterface
{
-
- private $name;
-
- private $path;
-
- public function __construct(string $name, PathInterface $path)
- {
- $this->name = $name;
- $this->path = $path;
+ public function __construct(
+ private readonly string $name,
+ private readonly PathInterface $path,
+ ) {
}
public function getName(): string
@@ -28,4 +23,12 @@ public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(?PathInterface $path = null, ?string $name = null): BeforePropertyEventInterface
+ {
+ return new self(
+ name: $name ?? $this->name,
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/BeforePropertyEventInterface.php b/src/Event/BeforePropertyEventInterface.php
index 2b62982..904b708 100644
--- a/src/Event/BeforePropertyEventInterface.php
+++ b/src/Event/BeforePropertyEventInterface.php
@@ -4,6 +4,9 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface BeforePropertyEventInterface extends PropertyEventInterface
{
+ public function with(?PathInterface $path = null, ?string $name = null): BeforePropertyEventInterface;
}
diff --git a/src/Event/ElementEventInterface.php b/src/Event/ElementEventInterface.php
index 3dc624d..261adaf 100644
--- a/src/Event/ElementEventInterface.php
+++ b/src/Event/ElementEventInterface.php
@@ -4,8 +4,11 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface ElementEventInterface extends EventInterface
{
-
public function getIndex(): int;
+
+ public function with(?PathInterface $path = null, ?int $index = null,): ElementEventInterface;
}
diff --git a/src/Event/EventInterface.php b/src/Event/EventInterface.php
index 05dc43a..a491bfd 100644
--- a/src/Event/EventInterface.php
+++ b/src/Event/EventInterface.php
@@ -8,6 +8,7 @@
interface EventInterface
{
-
public function getPath(): PathInterface;
+
+ public function with(?PathInterface $path = null): EventInterface;
}
diff --git a/src/Event/Exception/InvalidScalarDataException.php b/src/Event/Exception/InvalidScalarDataException.php
index 5dd3474..8aec0b0 100644
--- a/src/Event/Exception/InvalidScalarDataException.php
+++ b/src/Event/Exception/InvalidScalarDataException.php
@@ -10,16 +10,14 @@
final class InvalidScalarDataException extends LogicException implements ExceptionInterface, DataAwareInterface
{
-
- private $data;
-
- public function __construct($data, Throwable $previous = null)
- {
- $this->data = $data;
- parent::__construct("Invalid scalar data", 0, $previous);
+ public function __construct(
+ private readonly mixed $data,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Invalid scalar data", previous: $previous);
}
- public function getData()
+ public function getData(): mixed
{
return $this->data;
}
diff --git a/src/Event/PropertyEventInterface.php b/src/Event/PropertyEventInterface.php
index 13be97b..a68afd4 100644
--- a/src/Event/PropertyEventInterface.php
+++ b/src/Event/PropertyEventInterface.php
@@ -4,8 +4,11 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface PropertyEventInterface extends EventInterface
{
-
public function getName(): string;
+
+ public function with(?PathInterface $path = null, ?string $name = null): PropertyEventInterface;
}
diff --git a/src/Event/ScalarEvent.php b/src/Event/ScalarEvent.php
index f46c7f0..934648d 100644
--- a/src/Event/ScalarEvent.php
+++ b/src/Event/ScalarEvent.php
@@ -6,23 +6,22 @@
use Remorhaz\JSON\Data\Path\PathInterface;
+use function is_scalar;
+
final class ScalarEvent implements ScalarEventInterface
{
-
- private $data;
-
- private $path;
-
- public function __construct($data, PathInterface $path)
- {
- if (null !== $data && !is_scalar($data)) {
- throw new Exception\InvalidScalarDataException($data);
- }
- $this->data = $data;
- $this->path = $path;
+ private int|string|float|bool|null $data;
+
+ public function __construct(
+ mixed $data,
+ private readonly PathInterface $path,
+ ) {
+ $this->data = null === $data || is_scalar($data)
+ ? $data
+ : throw new Exception\InvalidScalarDataException($data);
}
- public function getData()
+ public function getData(): int|string|float|bool|null
{
return $this->data;
}
@@ -31,4 +30,15 @@ public function getPath(): PathInterface
{
return $this->path;
}
+
+ public function with(
+ ?PathInterface $path = null,
+ float|bool|int|string|null $data = null,
+ bool $forceData = false,
+ ): ScalarEventInterface {
+ return new self(
+ data: $forceData ? $data : ($data ?? $this->data),
+ path: $path ?? $this->path,
+ );
+ }
}
diff --git a/src/Event/ScalarEventInterface.php b/src/Event/ScalarEventInterface.php
index 5452228..7fabd38 100644
--- a/src/Event/ScalarEventInterface.php
+++ b/src/Event/ScalarEventInterface.php
@@ -4,8 +4,15 @@
namespace Remorhaz\JSON\Data\Event;
+use Remorhaz\JSON\Data\Path\PathInterface;
+
interface ScalarEventInterface extends EventInterface
{
+ public function getData(): int|string|float|bool|null;
- public function getData();
+ public function with(
+ ?PathInterface $path = null,
+ int|string|float|bool|null $data = null,
+ bool $forceData = false,
+ ): ScalarEventInterface;
}
diff --git a/src/Export/EventDecoder.php b/src/Export/EventDecoder.php
index e97ddd1..7f248e1 100644
--- a/src/Export/EventDecoder.php
+++ b/src/Export/EventDecoder.php
@@ -20,9 +20,8 @@
final class EventDecoder implements EventDecoderInterface
{
-
/**
- * @param Iterator|EventInterface[] $events
+ * @param Iterator $events
* @return NodeValueInterface|null
*/
public function exportEvents(Iterator $events): ?NodeValueInterface
@@ -76,13 +75,12 @@ public function exportEvents(Iterator $events): ?NodeValueInterface
return (new NodeValueFactory())->createValue($data);
}
+ /**
+ * @param Iterator $events
+ * @return NodeValueInterface
+ */
public function exportExistingEvents(Iterator $events): NodeValueInterface
{
- $value = $this->exportEvents($events);
- if (isset($value)) {
- return $value;
- }
-
- throw new Exception\NoValueToExportException();
+ return $this->exportEvents($events) ?? throw new Exception\NoValueToExportException();
}
}
diff --git a/src/Export/EventExporterInterface.php b/src/Export/EventExporterInterface.php
index 4f7053b..31b6a91 100644
--- a/src/Export/EventExporterInterface.php
+++ b/src/Export/EventExporterInterface.php
@@ -10,12 +10,15 @@
interface EventExporterInterface
{
-
/**
- * @param Iterator|EventInterface[] $events
+ * @param Iterator $events
* @return NodeValueInterface|null
*/
public function exportEvents(Iterator $events): ?NodeValueInterface;
+ /**
+ * @param Iterator $events
+ * @return NodeValueInterface
+ */
public function exportExistingEvents(Iterator $events): NodeValueInterface;
}
diff --git a/src/Export/Exception/EncodingFailedException.php b/src/Export/Exception/EncodingFailedException.php
index 36ed8bf..3e784f2 100644
--- a/src/Export/Exception/EncodingFailedException.php
+++ b/src/Export/Exception/EncodingFailedException.php
@@ -10,16 +10,14 @@
final class EncodingFailedException extends LogicException implements ExceptionInterface, DataAwareInterface
{
-
- private $data;
-
- public function __construct($data, Throwable $previous = null)
- {
- $this->data = $data;
- parent::__construct("Failed to encode data to JSON", 0, $previous);
+ public function __construct(
+ private readonly mixed $data,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Failed to encode data to JSON", previous: $previous);
}
- public function getData()
+ public function getData(): mixed
{
return $this->data;
}
diff --git a/src/Export/Exception/NoValueToExportException.php b/src/Export/Exception/NoValueToExportException.php
index 07281a2..4ca6c88 100644
--- a/src/Export/Exception/NoValueToExportException.php
+++ b/src/Export/Exception/NoValueToExportException.php
@@ -9,9 +9,8 @@
final class NoValueToExportException extends LogicException implements ExceptionInterface
{
-
- public function __construct(Throwable $previous = null)
+ public function __construct(?Throwable $previous = null)
{
- parent::__construct("No value to export", 0, $previous);
+ parent::__construct("No value to export", previous: $previous);
}
}
diff --git a/src/Export/Exception/UnexpectedValueException.php b/src/Export/Exception/UnexpectedValueException.php
index 1cd38b6..3d2d783 100644
--- a/src/Export/Exception/UnexpectedValueException.php
+++ b/src/Export/Exception/UnexpectedValueException.php
@@ -10,13 +10,11 @@
final class UnexpectedValueException extends DomainException implements ExceptionInterface
{
-
- private $value;
-
- public function __construct(ValueInterface $value, Throwable $previous = null)
- {
- $this->value = $value;
- parent::__construct("Unexpected value", 0, $previous);
+ public function __construct(
+ private ValueInterface $value,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Unexpected value", previous: $previous);
}
public function getValue(): ValueInterface
diff --git a/src/Export/Exception/UnknownEventException.php b/src/Export/Exception/UnknownEventException.php
index c99b1ed..ba254c7 100644
--- a/src/Export/Exception/UnknownEventException.php
+++ b/src/Export/Exception/UnknownEventException.php
@@ -10,13 +10,11 @@
final class UnknownEventException extends LogicException implements ExceptionInterface
{
-
- private $event;
-
- public function __construct(EventInterface $event, Throwable $previous = null)
- {
- $this->event = $event;
- parent::__construct("Unknown event", 0, $previous);
+ public function __construct(
+ private readonly EventInterface $event,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Unknown event", previous: $previous);
}
public function getEvent(): EventInterface
diff --git a/src/Export/ValueDecoder.php b/src/Export/ValueDecoder.php
index be200e4..0367d13 100644
--- a/src/Export/ValueDecoder.php
+++ b/src/Export/ValueDecoder.php
@@ -11,31 +11,34 @@
final class ValueDecoder implements ValueDecoderInterface
{
-
- public function exportValue(ValueInterface $value)
+ public function exportValue(ValueInterface $value): mixed
{
- if ($value instanceof ScalarValueInterface) {
- return $value->getData();
- }
-
- if ($value instanceof ArrayValueInterface) {
- $result = [];
- foreach ($value->createChildIterator() as $index => $element) {
- $result[$index] = $this->exportValue($element);
- }
+ return match (true) {
+ $value instanceof ScalarValueInterface => $value->getData(),
+ $value instanceof ArrayValueInterface => $this->exportArrayValue($value),
+ $value instanceof ObjectValueInterface => $this->exportObjectValue($value),
+ default => throw new Exception\UnexpectedValueException($value),
+ };
+ }
- return $result;
+ private function exportArrayValue(ArrayValueInterface $value): array
+ {
+ $result = [];
+ foreach ($value->createChildIterator() as $index => $element) {
+ /** @psalm-var mixed */
+ $result[$index] = $this->exportValue($element);
}
- if ($value instanceof ObjectValueInterface) {
- $result = (object) [];
- foreach ($value->createChildIterator() as $name => $property) {
- $result->{$name} = $this->exportValue($property);
- }
+ return $result;
+ }
- return $result;
+ private function exportObjectValue(ObjectValueInterface $value): object
+ {
+ $result = (object) [];
+ foreach ($value->createChildIterator() as $name => $property) {
+ $result->{$name} = $this->exportValue($property);
}
- throw new Exception\UnexpectedValueException($value);
+ return $result;
}
}
diff --git a/src/Export/ValueEncoder.php b/src/Export/ValueEncoder.php
index 1337c5e..06d82cb 100644
--- a/src/Export/ValueEncoder.php
+++ b/src/Export/ValueEncoder.php
@@ -18,23 +18,21 @@
*/
final class ValueEncoder implements ValueEncoderInterface
{
-
- private $decoder;
-
- public function __construct(ValueDecoderInterface $decoder)
- {
- $this->decoder = $decoder;
+ public function __construct(
+ private readonly ValueDecoderInterface $decoder,
+ ) {
}
public function exportValue(ValueInterface $value): string
{
+ /** @psalm-var mixed $decodedValue */
$decodedValue = $this
->decoder
->exportValue($value);
try {
return json_encode(
$decodedValue,
- JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR
+ JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR,
);
} catch (Throwable $e) {
throw new Exception\EncodingFailedException($decodedValue, $e);
diff --git a/src/Export/ValueEncoderInterface.php b/src/Export/ValueEncoderInterface.php
index 965cb1b..c851e79 100644
--- a/src/Export/ValueEncoderInterface.php
+++ b/src/Export/ValueEncoderInterface.php
@@ -8,6 +8,5 @@
interface ValueEncoderInterface extends ValueExporterInterface
{
-
public function exportValue(ValueInterface $value): string;
}
diff --git a/src/Export/ValueExporterInterface.php b/src/Export/ValueExporterInterface.php
index 719cd75..87175f0 100644
--- a/src/Export/ValueExporterInterface.php
+++ b/src/Export/ValueExporterInterface.php
@@ -8,6 +8,5 @@
interface ValueExporterInterface
{
-
- public function exportValue(ValueInterface $value);
+ public function exportValue(ValueInterface $value): mixed;
}
diff --git a/src/Path/Exception/ParentNotFoundException.php b/src/Path/Exception/ParentNotFoundException.php
index 7395ab5..4ff498e 100644
--- a/src/Path/Exception/ParentNotFoundException.php
+++ b/src/Path/Exception/ParentNotFoundException.php
@@ -13,13 +13,11 @@
final class ParentNotFoundException extends LogicException implements ExceptionInterface, PathAwareInterface
{
-
- private $path;
-
- public function __construct(PathInterface $path, Throwable $previous = null)
- {
- $this->path = $path;
- parent::__construct("Parent not found in path {$this->buildPath()}", 0, $previous);
+ public function __construct(
+ private readonly PathInterface $path,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Parent not found in path {$this->buildPath()}", previous: $previous);
}
public function getPath(): PathInterface
diff --git a/src/Path/Path.php b/src/Path/Path.php
index 3416ab4..468121d 100644
--- a/src/Path/Path.php
+++ b/src/Path/Path.php
@@ -5,16 +5,19 @@
namespace Remorhaz\JSON\Data\Path;
use function array_slice;
+use function array_values;
use function count;
final class Path implements PathInterface
{
+ /**
+ * @var list
+ */
+ private array $elements;
- private $elements;
-
- public function __construct(...$elements)
+ public function __construct(int|string ...$elements)
{
- $this->elements = $elements;
+ $this->elements = array_values($elements);
}
public function copyWithElement(int $index): PathInterface
@@ -29,13 +32,14 @@ public function copyWithProperty(string $name): PathInterface
public function copyParent(): PathInterface
{
- if (empty($this->elements)) {
- throw new Exception\ParentNotFoundException($this);
- }
-
- return new self(...array_slice($this->elements, 0, -1));
+ return empty($this->elements)
+ ? throw new Exception\ParentNotFoundException($this)
+ : new self(...array_slice($this->elements, 0, -1));
}
+ /**
+ * @return list
+ */
public function getElements(): array
{
return $this->elements;
diff --git a/src/Path/PathAwareInterface.php b/src/Path/PathAwareInterface.php
index ddb8545..4fbac95 100644
--- a/src/Path/PathAwareInterface.php
+++ b/src/Path/PathAwareInterface.php
@@ -6,6 +6,5 @@
interface PathAwareInterface
{
-
public function getPath(): PathInterface;
}
diff --git a/src/Path/PathInterface.php b/src/Path/PathInterface.php
index 8da0f6f..f548e1a 100644
--- a/src/Path/PathInterface.php
+++ b/src/Path/PathInterface.php
@@ -6,13 +6,15 @@
interface PathInterface
{
-
public function copyWithElement(int $index): PathInterface;
public function copyWithProperty(string $name): PathInterface;
public function copyParent(): PathInterface;
+ /**
+ * @return list
+ */
public function getElements(): array;
public function equals(PathInterface $path): bool;
diff --git a/src/Value/ArrayValueInterface.php b/src/Value/ArrayValueInterface.php
index 44e26bc..288e3c9 100644
--- a/src/Value/ArrayValueInterface.php
+++ b/src/Value/ArrayValueInterface.php
@@ -4,6 +4,12 @@
namespace Remorhaz\JSON\Data\Value;
+use Iterator;
+
interface ArrayValueInterface extends StructValueInterface
{
+ /**
+ * @return Iterator
+ */
+ public function createChildIterator(): Iterator;
}
diff --git a/src/Value/DataAwareInterface.php b/src/Value/DataAwareInterface.php
index 28d619c..9906e0c 100644
--- a/src/Value/DataAwareInterface.php
+++ b/src/Value/DataAwareInterface.php
@@ -6,6 +6,5 @@
interface DataAwareInterface
{
-
- public function getData();
+ public function getData(): mixed;
}
diff --git a/src/Value/DecodedJson/Exception/InvalidElementKeyException.php b/src/Value/DecodedJson/Exception/InvalidElementKeyException.php
index 6be1bb6..8159108 100644
--- a/src/Value/DecodedJson/Exception/InvalidElementKeyException.php
+++ b/src/Value/DecodedJson/Exception/InvalidElementKeyException.php
@@ -16,21 +16,12 @@
class InvalidElementKeyException extends RuntimeException implements ExceptionInterface, PathAwareInterface
{
-
- private $key;
-
- private $path;
-
- /**
- * @param mixed $key
- * @param PathInterface $path
- * @param Throwable|null $previous
- */
- public function __construct($key, PathInterface $path, Throwable $previous = null)
- {
- $this->key = $key;
- $this->path = $path;
- parent::__construct($this->buildMessage(), 0, $previous);
+ public function __construct(
+ private readonly mixed $key,
+ private readonly PathInterface $path,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct($this->buildMessage(), previous: $previous);
}
private function buildMessage(): string
@@ -38,7 +29,7 @@ private function buildMessage(): string
return "Invalid element key in decoded JSON: {$this->buildKey()} at {$this->buildPath()}";
}
- public function getKey()
+ public function getKey(): mixed
{
return $this->key;
}
diff --git a/src/Value/DecodedJson/Exception/InvalidNodeDataException.php b/src/Value/DecodedJson/Exception/InvalidNodeDataException.php
index 6701bd4..f6809ca 100644
--- a/src/Value/DecodedJson/Exception/InvalidNodeDataException.php
+++ b/src/Value/DecodedJson/Exception/InvalidNodeDataException.php
@@ -16,16 +16,12 @@ class InvalidNodeDataException extends RuntimeException implements
PathAwareInterface,
DataAwareInterface
{
-
- private $data;
-
- private $path;
-
- public function __construct($data, PathInterface $path, Throwable $previous = null)
- {
- $this->data = $data;
- $this->path = $path;
- parent::__construct($this->buildMessage(), 0, $previous);
+ public function __construct(
+ private readonly mixed $data,
+ private readonly PathInterface $path,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct($this->buildMessage(), previous: $previous);
}
private function buildMessage(): string
@@ -33,7 +29,7 @@ private function buildMessage(): string
return "Invalid data in decoded JSON at {$this->buildPath()}";
}
- public function getData()
+ public function getData(): mixed
{
return $this->data;
}
diff --git a/src/Value/DecodedJson/NodeArrayValue.php b/src/Value/DecodedJson/NodeArrayValue.php
index 9d8fd4b..5add4aa 100644
--- a/src/Value/DecodedJson/NodeArrayValue.php
+++ b/src/Value/DecodedJson/NodeArrayValue.php
@@ -9,30 +9,26 @@
use Remorhaz\JSON\Data\Path\PathInterface;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
+use function is_int;
+
final class NodeArrayValue implements NodeValueInterface, ArrayValueInterface
{
-
- private $data;
-
- private $path;
-
- private $valueFactory;
-
public function __construct(
- array $data,
- PathInterface $path,
- NodeValueFactoryInterface $valueFactory
+ private readonly array $data,
+ private readonly PathInterface $path,
+ private readonly NodeValueFactoryInterface $valueFactory,
) {
- $this->data = $data;
- $this->path = $path;
- $this->valueFactory = $valueFactory;
}
+ /**
+ * @return Iterator
+ */
public function createChildIterator(): Iterator
{
$validIndex = 0;
+ /** @psalm-var mixed $element */
foreach ($this->data as $index => $element) {
- if ($index !== $validIndex++) {
+ if (!is_int($index) || $index != $validIndex++) {
throw new Exception\InvalidElementKeyException($index, $this->path);
}
yield $index => $this
diff --git a/src/Value/DecodedJson/NodeObjectValue.php b/src/Value/DecodedJson/NodeObjectValue.php
index 318b3c5..2b56a2f 100644
--- a/src/Value/DecodedJson/NodeObjectValue.php
+++ b/src/Value/DecodedJson/NodeObjectValue.php
@@ -4,40 +4,28 @@
namespace Remorhaz\JSON\Data\Value\DecodedJson;
-use Generator;
use Iterator;
use Remorhaz\JSON\Data\Value\ObjectValueInterface;
use Remorhaz\JSON\Data\Path\PathInterface;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
-use stdClass;
final class NodeObjectValue implements NodeValueInterface, ObjectValueInterface
{
-
- private $data;
-
- private $path;
-
- private $valueFactory;
-
public function __construct(
- stdClass $data,
- PathInterface $path,
- NodeValueFactoryInterface $valueFactory
+ private readonly object $data,
+ private readonly PathInterface $path,
+ private readonly NodeValueFactoryInterface $valueFactory,
) {
- $this->data = $data;
- $this->path = $path;
- $this->valueFactory = $valueFactory;
}
+ /**
+ * @return Iterator
+ */
public function createChildIterator(): Iterator
{
- return $this->createChildGenerator();
- }
-
- private function createChildGenerator(): Generator
- {
+ /** @psalm-var mixed $property */
foreach (get_object_vars($this->data) as $name => $property) {
+ /** @psalm-suppress RedundantCast */
$stringName = (string) $name;
yield $stringName => $this
->valueFactory
diff --git a/src/Value/DecodedJson/NodeScalarValue.php b/src/Value/DecodedJson/NodeScalarValue.php
index b106765..04347de 100644
--- a/src/Value/DecodedJson/NodeScalarValue.php
+++ b/src/Value/DecodedJson/NodeScalarValue.php
@@ -8,23 +8,22 @@
use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
+use function is_scalar;
+
final class NodeScalarValue implements NodeValueInterface, ScalarValueInterface
{
-
- private $data;
-
- private $path;
-
- public function __construct($data, PathInterface $path)
- {
- if (null !== $data && !is_scalar($data)) {
- throw new Exception\InvalidNodeDataException($data, $path);
- }
- $this->data = $data;
- $this->path = $path;
+ private int|float|string|bool|null $data;
+
+ public function __construct(
+ mixed $data,
+ private readonly PathInterface $path,
+ ) {
+ $this->data = null === $data || is_scalar($data)
+ ? $data
+ : throw new Exception\InvalidNodeDataException($data, $path);
}
- public function getData()
+ public function getData(): int|float|string|bool|null
{
return $this->data;
}
diff --git a/src/Value/DecodedJson/NodeValueFactory.php b/src/Value/DecodedJson/NodeValueFactory.php
index 5853b50..33f7c15 100644
--- a/src/Value/DecodedJson/NodeValueFactory.php
+++ b/src/Value/DecodedJson/NodeValueFactory.php
@@ -7,14 +7,13 @@
use Remorhaz\JSON\Data\Path\Path;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Remorhaz\JSON\Data\Path\PathInterface;
-use stdClass;
use function is_array;
+use function is_object;
use function is_scalar;
final class NodeValueFactory implements NodeValueFactoryInterface
{
-
public static function create(): NodeValueFactoryInterface
{
return new self();
@@ -22,28 +21,17 @@ public static function create(): NodeValueFactoryInterface
/**
* {@inheritDoc}
- *
- * @param array|bool|float|int|stdClass|string|null $data
- * @param PathInterface|null $path
- * @return NodeValueInterface
*/
- public function createValue($data, ?PathInterface $path = null): NodeValueInterface
+ public function createValue(mixed $data, ?PathInterface $path = null): NodeValueInterface
{
- if (!isset($path)) {
- $path = new Path();
- }
- if (null === $data || is_scalar($data)) {
- return new NodeScalarValue($data, $path);
- }
-
- if (is_array($data)) {
- return new NodeArrayValue($data, $path, $this);
- }
-
- if ($data instanceof stdClass) {
- return new NodeObjectValue($data, $path, $this);
- }
-
- throw new Exception\InvalidNodeDataException($data, $path);
+ $path ??= new Path();
+
+ return match (true) {
+ null === $data,
+ is_scalar($data) => new NodeScalarValue($data, $path),
+ is_array($data) => new NodeArrayValue($data, $path, $this),
+ is_object($data) => new NodeObjectValue($data, $path, $this),
+ default => throw new Exception\InvalidNodeDataException($data, $path),
+ };
}
}
diff --git a/src/Value/DecodedJson/NodeValueFactoryInterface.php b/src/Value/DecodedJson/NodeValueFactoryInterface.php
index 8b6af20..cc83459 100644
--- a/src/Value/DecodedJson/NodeValueFactoryInterface.php
+++ b/src/Value/DecodedJson/NodeValueFactoryInterface.php
@@ -6,17 +6,11 @@
use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Remorhaz\JSON\Data\Path\PathInterface;
-use stdClass;
interface NodeValueFactoryInterface
{
-
/**
* Converts decoded JSON to JSON node value.
- *
- * @param array|bool|float|int|stdClass|string|null $data
- * @param PathInterface|null $path
- * @return NodeValueInterface
*/
- public function createValue($data, ?PathInterface $path = null): NodeValueInterface;
+ public function createValue(mixed $data, ?PathInterface $path = null): NodeValueInterface;
}
diff --git a/src/Value/EncodedJson/Exception/JsonNotDecodedException.php b/src/Value/EncodedJson/Exception/JsonNotDecodedException.php
index 0cf8fe1..5d71077 100644
--- a/src/Value/EncodedJson/Exception/JsonNotDecodedException.php
+++ b/src/Value/EncodedJson/Exception/JsonNotDecodedException.php
@@ -9,13 +9,11 @@
final class JsonNotDecodedException extends RuntimeException implements ExceptionInterface
{
-
- private $json;
-
- public function __construct(string $json, Throwable $previous = null)
- {
- $this->json = $json;
- parent::__construct("Failed to decode JSON", 0, $previous);
+ public function __construct(
+ private readonly string $json,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Failed to decode JSON", previous: $previous);
}
public function getJson(): string
diff --git a/src/Value/EncodedJson/NodeValueFactory.php b/src/Value/EncodedJson/NodeValueFactory.php
index aca7845..1b8a1d8 100644
--- a/src/Value/EncodedJson/NodeValueFactory.php
+++ b/src/Value/EncodedJson/NodeValueFactory.php
@@ -5,8 +5,7 @@
namespace Remorhaz\JSON\Data\Value\EncodedJson;
use Remorhaz\JSON\Data\Path\PathInterface;
-use Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactory as DecodedJsonNodeValueFactory;
-use Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactoryInterface as DecodedJsonNodeValueFactoryInterface;
+use Remorhaz\JSON\Data\Value\DecodedJson;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
use Throwable;
@@ -16,22 +15,20 @@
final class NodeValueFactory implements NodeValueFactoryInterface
{
-
- private $decodedJsonNodeValueFactory;
-
public static function create(): NodeValueFactoryInterface
{
- return new self(DecodedJsonNodeValueFactory::create());
+ return new self(DecodedJson\NodeValueFactory::create());
}
- public function __construct(DecodedJsonNodeValueFactoryInterface $decodedJsonNodeValueFactory)
- {
- $this->decodedJsonNodeValueFactory = $decodedJsonNodeValueFactory;
+ public function __construct(
+ private readonly DecodedJson\NodeValueFactoryInterface $decodedJsonNodeValueFactory,
+ ) {
}
public function createValue(string $json, ?PathInterface $path = null): NodeValueInterface
{
try {
+ /** @psalm-var mixed $decodedData */
$decodedData = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
} catch (Throwable $e) {
throw new Exception\JsonNotDecodedException($json, $e);
diff --git a/src/Value/EncodedJson/NodeValueFactoryInterface.php b/src/Value/EncodedJson/NodeValueFactoryInterface.php
index fe5713a..7fa0097 100644
--- a/src/Value/EncodedJson/NodeValueFactoryInterface.php
+++ b/src/Value/EncodedJson/NodeValueFactoryInterface.php
@@ -9,6 +9,5 @@
interface NodeValueFactoryInterface
{
-
public function createValue(string $json, ?PathInterface $path = null): NodeValueInterface;
}
diff --git a/src/Value/ObjectValueInterface.php b/src/Value/ObjectValueInterface.php
index 20d62c1..b637ae4 100644
--- a/src/Value/ObjectValueInterface.php
+++ b/src/Value/ObjectValueInterface.php
@@ -4,6 +4,12 @@
namespace Remorhaz\JSON\Data\Value;
+use Iterator;
+
interface ObjectValueInterface extends StructValueInterface
{
+ /**
+ * @return Iterator
+ */
+ public function createChildIterator(): Iterator;
}
diff --git a/src/Value/ScalarValueInterface.php b/src/Value/ScalarValueInterface.php
index 8abcef1..95e0e57 100644
--- a/src/Value/ScalarValueInterface.php
+++ b/src/Value/ScalarValueInterface.php
@@ -6,4 +6,5 @@
interface ScalarValueInterface extends ValueInterface, DataAwareInterface
{
+ public function getData(): int|float|string|bool|null;
}
diff --git a/src/Value/StructValueInterface.php b/src/Value/StructValueInterface.php
index 4a82bec..d51d686 100644
--- a/src/Value/StructValueInterface.php
+++ b/src/Value/StructValueInterface.php
@@ -8,6 +8,8 @@
interface StructValueInterface extends ValueInterface
{
-
+ /**
+ * @return Iterator
+ */
public function createChildIterator(): Iterator;
}
diff --git a/src/Walker/EventGenerator.php b/src/Walker/EventGenerator.php
index 2b65efe..543c277 100644
--- a/src/Walker/EventGenerator.php
+++ b/src/Walker/EventGenerator.php
@@ -4,7 +4,7 @@
namespace Remorhaz\JSON\Data\Walker;
-use Generator;
+use Iterator;
use Remorhaz\JSON\Data\Event\AfterArrayEvent;
use Remorhaz\JSON\Data\Event\AfterElementEvent;
use Remorhaz\JSON\Data\Event\AfterElementEventInterface;
@@ -27,18 +27,22 @@
final class EventGenerator
{
-
- private $stack;
-
- private $path;
-
- public function __construct(NodeValueInterface $value, PathInterface $path)
- {
+ /**
+ * @var list
+ */
+ private array $stack;
+
+ public function __construct(
+ NodeValueInterface $value,
+ private PathInterface $path,
+ ) {
$this->stack = [$value];
- $this->path = $path;
}
- public function __invoke(): Generator
+ /**
+ * @return Iterator
+ */
+ public function __invoke(): Iterator
{
while (true) {
if (empty($this->stack)) {
@@ -68,7 +72,11 @@ public function __invoke(): Generator
}
}
- private function onEvent(EventInterface $event): Generator
+ /**
+ * @param EventInterface $event
+ * @return Iterator
+ */
+ private function onEvent(EventInterface $event): Iterator
{
switch (true) {
case $event instanceof BeforeElementEventInterface:
@@ -93,12 +101,20 @@ private function onEvent(EventInterface $event): Generator
yield $event;
}
- private function onScalarValue(ScalarValueInterface $value): Generator
+ /**
+ * @param ScalarValueInterface $value
+ * @return Iterator
+ */
+ private function onScalarValue(ScalarValueInterface $value): Iterator
{
yield new ScalarEvent($value->getData(), $this->path);
}
- private function onArrayValue(ArrayValueInterface $value): Generator
+ /**
+ * @param ArrayValueInterface $value
+ * @return Iterator
+ */
+ private function onArrayValue(ArrayValueInterface $value): Iterator
{
$localStack = [];
foreach ($value->createChildIterator() as $index => $child) {
@@ -109,18 +125,22 @@ private function onArrayValue(ArrayValueInterface $value): Generator
$localStack,
new BeforeElementEvent($index, $elementPath),
$child,
- new AfterElementEvent($index, $elementPath)
+ new AfterElementEvent($index, $elementPath),
);
}
array_push(
$this->stack,
new AfterArrayEvent($this->path),
- ...array_reverse($localStack)
+ ...array_reverse($localStack),
);
yield new BeforeArrayEvent($this->path);
}
- private function onObjectValue(ObjectValueInterface $value): Generator
+ /**
+ * @param ObjectValueInterface $value
+ * @return Iterator
+ */
+ private function onObjectValue(ObjectValueInterface $value): Iterator
{
$localStack = [];
foreach ($value->createChildIterator() as $name => $child) {
@@ -131,13 +151,13 @@ private function onObjectValue(ObjectValueInterface $value): Generator
$localStack,
new BeforePropertyEvent($name, $elementPath),
$child,
- new AfterPropertyEvent($name, $elementPath)
+ new AfterPropertyEvent($name, $elementPath),
);
}
array_push(
$this->stack,
new AfterObjectEvent($this->path),
- ...array_reverse($localStack)
+ ...array_reverse($localStack),
);
yield new BeforeObjectEvent($this->path);
}
diff --git a/src/Walker/Exception/UnexpectedEntityException.php b/src/Walker/Exception/UnexpectedEntityException.php
index 30da8ab..15daff8 100644
--- a/src/Walker/Exception/UnexpectedEntityException.php
+++ b/src/Walker/Exception/UnexpectedEntityException.php
@@ -9,16 +9,14 @@
final class UnexpectedEntityException extends LogicException implements ExceptionInterface
{
-
- private $entity;
-
- public function __construct($entity, Throwable $previous = null)
- {
- $this->entity = $entity;
- parent::__construct("Invalid entity", 0, $previous);
+ public function __construct(
+ private readonly mixed $entity,
+ ?Throwable $previous = null,
+ ) {
+ parent::__construct("Invalid entity", previous: $previous);
}
- public function getEntity()
+ public function getEntity(): mixed
{
return $this->entity;
}
diff --git a/src/Walker/MutationInterface.php b/src/Walker/MutationInterface.php
index c88fd6e..c8d3e36 100644
--- a/src/Walker/MutationInterface.php
+++ b/src/Walker/MutationInterface.php
@@ -4,12 +4,17 @@
namespace Remorhaz\JSON\Data\Walker;
+use Iterator;
use Remorhaz\JSON\Data\Event\EventInterface;
interface MutationInterface
{
-
- public function __invoke(EventInterface $event, ValueWalkerInterface $valueWalker);
+ /**
+ * @param EventInterface $event
+ * @param ValueWalkerInterface $valueWalker
+ * @return Iterator
+ */
+ public function __invoke(EventInterface $event, ValueWalkerInterface $valueWalker): Iterator;
public function reset(): void;
}
diff --git a/src/Walker/ValueWalker.php b/src/Walker/ValueWalker.php
index b0f0e9e..4923a49 100644
--- a/src/Walker/ValueWalker.php
+++ b/src/Walker/ValueWalker.php
@@ -5,21 +5,32 @@
namespace Remorhaz\JSON\Data\Walker;
use Iterator;
+use Remorhaz\JSON\Data\Event\EventInterface;
use Remorhaz\JSON\Data\Path\PathInterface;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
final class ValueWalker implements ValueWalkerInterface
{
-
+ /**
+ * @param NodeValueInterface $value
+ * @param PathInterface $path
+ * @return Iterator
+ */
public function createEventIterator(NodeValueInterface $value, PathInterface $path): Iterator
{
return (new EventGenerator($value, $path))();
}
+ /**
+ * @param NodeValueInterface $value
+ * @param PathInterface $path
+ * @param MutationInterface $modifier
+ * @return Iterator
+ */
public function createMutableEventIterator(
NodeValueInterface $value,
PathInterface $path,
- MutationInterface $modifier
+ MutationInterface $modifier,
): Iterator {
$modifier->reset();
foreach ($this->createEventIterator($value, $path) as $event) {
diff --git a/src/Walker/ValueWalkerInterface.php b/src/Walker/ValueWalkerInterface.php
index 6bbb28c..f9e4af7 100644
--- a/src/Walker/ValueWalkerInterface.php
+++ b/src/Walker/ValueWalkerInterface.php
@@ -10,7 +10,6 @@
interface ValueWalkerInterface
{
-
public function createEventIterator(NodeValueInterface $value, PathInterface $path): Iterator;
public function createMutableEventIterator(
diff --git a/tests/Comparator/ContainsValueComparatorTest.php b/tests/Comparator/ContainsValueComparatorTest.php
index f8bd7c4..53c064e 100644
--- a/tests/Comparator/ContainsValueComparatorTest.php
+++ b/tests/Comparator/ContainsValueComparatorTest.php
@@ -6,6 +6,8 @@
use Collator;
use Generator;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Comparator\ContainsValueComparator;
use Remorhaz\JSON\Data\Value\EncodedJson\NodeValueFactory;
@@ -13,29 +15,25 @@
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
use Remorhaz\JSON\Data\Value\ValueInterface;
-/**
- * @covers \Remorhaz\JSON\Data\Comparator\ContainsValueComparator
- */
+#[CoversClass(ContainsValueComparator::class)]
class ContainsValueComparatorTest extends TestCase
{
-
- /**
- * @param string $data
- * @param string $containedData
- * @dataProvider providerMatchingValues
- */
+ #[DataProvider('providerMatchingValues')]
public function testCompare_MatchingValues_ReturnsTrue(string $data, string $containedData): void
{
$comparator = new ContainsValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($data),
- $nodeValueFactory->createValue($containedData)
+ $nodeValueFactory->createValue($containedData),
);
self::assertTrue($actualValue);
}
- public function providerMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerMatchingValues(): iterable
{
return [
'Same string' => ['"a"', '"a"'],
@@ -56,23 +54,22 @@ public function providerMatchingValues(): array
];
}
- /**
- * @param string $data
- * @param string $containedData
- * @dataProvider providerNonMatchingValues
- */
+ #[DataProvider('providerNonMatchingValues')]
public function testCompare_NonMatchingValues_ReturnsFalse(string $data, string $containedData): void
{
$comparator = new ContainsValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($data),
- $nodeValueFactory->createValue($containedData)
+ $nodeValueFactory->createValue($containedData),
);
self::assertFalse($actualValue);
}
- public function providerNonMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerNonMatchingValues(): iterable
{
return [
'Array and scalar' => ['["a"]', '"a"'],
@@ -90,7 +87,7 @@ public function providerNonMatchingValues(): array
public function testCompare_DuplicatedPropertyInLeftValue_ReturnsFalse(): void
{
$comparator = new ContainsValueComparator(new Collator('UTF-8'));
- $value = $this->createMock(ScalarValueInterface::class);
+ $value = self::createStub(ScalarValueInterface::class);
$value
->method('getData')
->willReturn('b');
@@ -104,7 +101,7 @@ public function testCompare_DuplicatedPropertyInRightValue_ReturnsFalse(): void
{
$comparator = new ContainsValueComparator(new Collator('UTF-8'));
$leftValue = NodeValueFactory::create()->createValue('{"a":"b"}');
- $value = $this->createMock(ScalarValueInterface::class);
+ $value = self::createStub(ScalarValueInterface::class);
$value
->method('getData')
->willReturn('b');
@@ -115,7 +112,7 @@ public function testCompare_DuplicatedPropertyInRightValue_ReturnsFalse(): void
private function createObjectWithDuplicatedProperty(string $name, ValueInterface $value): ValueInterface
{
- $object = $this->createMock(ObjectValueInterface::class);
+ $object = self::createStub(ObjectValueInterface::class);
$generator = function () use ($name, $value): Generator {
yield $name => $value;
yield $name => $value;
diff --git a/tests/Comparator/EqualValueComparatorTest.php b/tests/Comparator/EqualValueComparatorTest.php
index 3daa7bf..850aef9 100644
--- a/tests/Comparator/EqualValueComparatorTest.php
+++ b/tests/Comparator/EqualValueComparatorTest.php
@@ -6,6 +6,8 @@
use Collator;
use Generator;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Comparator\EqualValueComparator;
use Remorhaz\JSON\Data\Value\EncodedJson\NodeValueFactory;
@@ -13,29 +15,25 @@
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
use Remorhaz\JSON\Data\Value\ValueInterface;
-/**
- * @covers \Remorhaz\JSON\Data\Comparator\EqualValueComparator
- */
+#[CoversClass(EqualValueComparator::class)]
class EqualValueComparatorTest extends TestCase
{
-
- /**
- * @param string $data
- * @param string $equalData
- * @dataProvider providerMatchingValues
- */
+ #[DataProvider('providerMatchingValues')]
public function testCompare_MatchingValues_ReturnsTrue(string $data, string $equalData): void
{
$comparator = new EqualValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($data),
- $nodeValueFactory->createValue($equalData)
+ $nodeValueFactory->createValue($equalData),
);
self::assertTrue($actualValue);
}
- public function providerMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerMatchingValues(): iterable
{
return [
'Same string' => ['"a"', '"a"'],
@@ -51,23 +49,22 @@ public function providerMatchingValues(): array
];
}
- /**
- * @param string $data
- * @param string $equalData
- * @dataProvider providerNonMatchingValues
- */
+ #[DataProvider('providerNonMatchingValues')]
public function testCompare_NonMatchingValues_ReturnsFalse(string $data, string $equalData): void
{
$comparator = new EqualValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($data),
- $nodeValueFactory->createValue($equalData)
+ $nodeValueFactory->createValue($equalData),
);
self::assertFalse($actualValue);
}
- public function providerNonMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerNonMatchingValues(): iterable
{
return [
'Array and scalar' => ['["a"]', '"a"'],
@@ -86,7 +83,7 @@ public function providerNonMatchingValues(): array
public function testCompare_DuplicatedPropertyInLeftValue_ReturnsFalse(): void
{
$comparator = new EqualValueComparator(new Collator('UTF-8'));
- $value = $this->createMock(ScalarValueInterface::class);
+ $value = self::createStub(ScalarValueInterface::class);
$value
->method('getData')
->willReturn('b');
@@ -100,7 +97,7 @@ public function testCompare_DuplicatedPropertyInRightValue_ReturnsFalse(): void
{
$comparator = new EqualValueComparator(new Collator('UTF-8'));
$leftValue = NodeValueFactory::create()->createValue('{"a":"b"}');
- $value = $this->createMock(ScalarValueInterface::class);
+ $value = self::createStub(ScalarValueInterface::class);
$value
->method('getData')
->willReturn('b');
@@ -111,7 +108,7 @@ public function testCompare_DuplicatedPropertyInRightValue_ReturnsFalse(): void
private function createObjectWithDuplicatedProperty(string $name, ValueInterface $value): ValueInterface
{
- $object = $this->createMock(ObjectValueInterface::class);
+ $object = self::createStub(ObjectValueInterface::class);
$generator = function () use ($name, $value): Generator {
yield $name => $value;
yield $name => $value;
diff --git a/tests/Comparator/GreaterValueComparatorTest.php b/tests/Comparator/GreaterValueComparatorTest.php
index 9f1e2ba..9644d02 100644
--- a/tests/Comparator/GreaterValueComparatorTest.php
+++ b/tests/Comparator/GreaterValueComparatorTest.php
@@ -5,33 +5,31 @@
namespace Remorhaz\JSON\Data\Test\Comparator;
use Collator;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Comparator\GreaterValueComparator;
use Remorhaz\JSON\Data\Value\EncodedJson\NodeValueFactory;
-/**
- * @covers \Remorhaz\JSON\Data\Comparator\GreaterValueComparator
- */
+#[CoversClass(GreaterValueComparator::class)]
class GreaterValueComparatorTest extends TestCase
{
-
- /**
- * @param string $leftData
- * @param string $rightData
- * @dataProvider providerMatchingValues
- */
+ #[DataProvider('providerMatchingValues')]
public function testCompare_MatchingValues_ReturnsTrue(string $leftData, string $rightData): void
{
$comparator = new GreaterValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($leftData),
- $nodeValueFactory->createValue($rightData)
+ $nodeValueFactory->createValue($rightData),
);
self::assertTrue($actualValue);
}
- public function providerMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerMatchingValues(): iterable
{
return [
'Left string is greater' => ['"b"', '"a"'],
@@ -41,23 +39,22 @@ public function providerMatchingValues(): array
];
}
- /**
- * @param string $leftData
- * @param string $rightData
- * @dataProvider providerNonMatchingValues
- */
+ #[DataProvider('providerNonMatchingValues')]
public function testCompare_NonMatchingValues_ReturnsFalse(string $leftData, string $rightData): void
{
$comparator = new GreaterValueComparator(new Collator('UTF-8'));
$nodeValueFactory = NodeValueFactory::create();
$actualValue = $comparator->compare(
$nodeValueFactory->createValue($leftData),
- $nodeValueFactory->createValue($rightData)
+ $nodeValueFactory->createValue($rightData),
);
self::assertFalse($actualValue);
}
- public function providerNonMatchingValues(): array
+ /**
+ * @return iterable
+ */
+ public static function providerNonMatchingValues(): iterable
{
return [
'Same string' => ['"a"', '"b"'],
diff --git a/tests/Event/AfterArrayEventTest.php b/tests/Event/AfterArrayEventTest.php
index 987d23e..6e0e31e 100644
--- a/tests/Event/AfterArrayEventTest.php
+++ b/tests/Event/AfterArrayEventTest.php
@@ -4,20 +4,41 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\AfterArrayEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\AfterArrayEvent
- */
+#[CoversClass(AfterArrayEvent::class)]
class AfterArrayEventTest extends TestCase
{
-
public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
{
$path = new Path();
$event = new AfterArrayEvent($path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new AfterArrayEvent($path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new AfterArrayEvent($oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new AfterArrayEvent(new Path());
+ self::assertNotSame($event, $event->with());
+ }
}
diff --git a/tests/Event/AfterElementEventTest.php b/tests/Event/AfterElementEventTest.php
index 49d9a29..37ddbf1 100644
--- a/tests/Event/AfterElementEventTest.php
+++ b/tests/Event/AfterElementEventTest.php
@@ -4,16 +4,14 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\AfterElementEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\AfterElementEvent
- */
+#[CoversClass(AfterElementEvent::class)]
class AfterElementEventTest extends TestCase
{
-
public function testGetIndex_ConstructedWithIndex_ReturnsSameIndex(): void
{
$event = new AfterElementEvent(1, new Path());
@@ -26,4 +24,41 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
$event = new AfterElementEvent(1, $path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new AfterElementEvent(1, $path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new AfterElementEvent(1, $oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new AfterElementEvent(1, new Path());
+ self::assertNotSame($event, $event->with());
+ }
+
+ public function testWith_GivenNoIndex_ResultHasOldIndex(): void
+ {
+ $event = new AfterElementEvent(1, new Path());
+ $clone = $event->with();
+ self::assertSame(1, $clone->getIndex());
+ }
+
+ public function testWith_GivenNewIndex_ResultHasNewIndex(): void
+ {
+ $event = new AfterElementEvent(1, new Path());
+ $clone = $event->with(index: 2);
+ self::assertSame(2, $clone->getIndex());
+ }
}
diff --git a/tests/Event/AfterObjectEventTest.php b/tests/Event/AfterObjectEventTest.php
index 08e25b2..a02f878 100644
--- a/tests/Event/AfterObjectEventTest.php
+++ b/tests/Event/AfterObjectEventTest.php
@@ -4,20 +4,41 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\AfterObjectEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\AfterObjectEvent
- */
+#[CoversClass(AfterObjectEvent::class)]
class AfterObjectEventTest extends TestCase
{
-
public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
{
$path = new Path();
$event = new AfterObjectEvent($path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new AfterObjectEvent($path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new AfterObjectEvent($oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new AfterObjectEvent(new Path());
+ self::assertNotSame($event, $event->with());
+ }
}
diff --git a/tests/Event/AfterPropertyEventTest.php b/tests/Event/AfterPropertyEventTest.php
index 102f8f7..f404fc6 100644
--- a/tests/Event/AfterPropertyEventTest.php
+++ b/tests/Event/AfterPropertyEventTest.php
@@ -4,16 +4,14 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\AfterPropertyEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\AfterPropertyEvent
- */
+#[CoversClass(AfterPropertyEvent::class)]
class AfterPropertyEventTest extends TestCase
{
-
public function testGetName_ConstructedWithName_ReturnsSameIndex(): void
{
$event = new AfterPropertyEvent('a', new Path());
@@ -26,4 +24,41 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
$event = new AfterPropertyEvent('a', $path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new AfterPropertyEvent('a', $path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new AfterPropertyEvent('a', $oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new AfterPropertyEvent('a', new Path());
+ self::assertNotSame($event, $event->with());
+ }
+
+ public function testWith_GivenNoName_ResultHasOldName(): void
+ {
+ $event = new AfterPropertyEvent('a', new Path());
+ $clone = $event->with();
+ self::assertSame('a', $clone->getName());
+ }
+
+ public function testWith_GivenNewName_ResultHasNewName(): void
+ {
+ $event = new AfterPropertyEvent('a', new Path());
+ $clone = $event->with(name: 'b');
+ self::assertSame('b', $clone->getName());
+ }
}
diff --git a/tests/Event/BeforeArrayEventTest.php b/tests/Event/BeforeArrayEventTest.php
index 32cce57..f20ed9d 100644
--- a/tests/Event/BeforeArrayEventTest.php
+++ b/tests/Event/BeforeArrayEventTest.php
@@ -4,20 +4,42 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\BeforeArrayEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\BeforeArrayEvent
- */
+#[CoversClass(BeforeArrayEvent::class)]
class BeforeArrayEventTest extends TestCase
{
-
public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
{
$path = new Path();
$event = new BeforeArrayEvent($path);
self::assertSame($path, $event->getPath());
}
+
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new BeforeArrayEvent($path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new BeforeArrayEvent($oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new BeforeArrayEvent(new Path());
+ self::assertNotSame($event, $event->with());
+ }
}
diff --git a/tests/Event/BeforeElementEventTest.php b/tests/Event/BeforeElementEventTest.php
index 7ed6b55..cfd90c3 100644
--- a/tests/Event/BeforeElementEventTest.php
+++ b/tests/Event/BeforeElementEventTest.php
@@ -4,16 +4,14 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\BeforeElementEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\BeforeElementEvent
- */
+#[CoversClass(BeforeElementEvent::class)]
class BeforeElementEventTest extends TestCase
{
-
public function testGetIndex_ConstructedWithIndex_ReturnsSameIndex(): void
{
$event = new BeforeElementEvent(1, new Path());
@@ -26,4 +24,41 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
$event = new BeforeElementEvent(1, $path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new BeforeElementEvent(1, $path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new BeforeElementEvent(1, $oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new BeforeElementEvent(1, new Path());
+ self::assertNotSame($event, $event->with());
+ }
+
+ public function testWith_GivenNoIndex_ResultHasOldIndex(): void
+ {
+ $event = new BeforeElementEvent(1, new Path());
+ $clone = $event->with();
+ self::assertSame(1, $clone->getIndex());
+ }
+
+ public function testWith_GivenNewIndex_ResultHasNewIndex(): void
+ {
+ $event = new BeforeElementEvent(1, new Path());
+ $clone = $event->with(index: 2);
+ self::assertSame(2, $clone->getIndex());
+ }
}
diff --git a/tests/Event/BeforeObjectEventTest.php b/tests/Event/BeforeObjectEventTest.php
index 451f3f9..239c47e 100644
--- a/tests/Event/BeforeObjectEventTest.php
+++ b/tests/Event/BeforeObjectEventTest.php
@@ -4,20 +4,41 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\BeforeObjectEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\BeforeObjectEvent
- */
+#[CoversClass(BeforeObjectEvent::class)]
class BeforeObjectEventTest extends TestCase
{
-
public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
{
$path = new Path();
$event = new BeforeObjectEvent($path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new BeforeObjectEvent($path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new BeforeObjectEvent($oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new BeforeObjectEvent(new Path());
+ self::assertNotSame($event, $event->with());
+ }
}
diff --git a/tests/Event/BeforePropertyEventTest.php b/tests/Event/BeforePropertyEventTest.php
index 48ef459..e6c011e 100644
--- a/tests/Event/BeforePropertyEventTest.php
+++ b/tests/Event/BeforePropertyEventTest.php
@@ -4,16 +4,14 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\BeforePropertyEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\BeforePropertyEvent
- */
+#[CoversClass(BeforePropertyEvent::class)]
class BeforePropertyEventTest extends TestCase
{
-
public function testGetName_ConstructedWithName_ReturnsSameIndex(): void
{
$event = new BeforePropertyEvent('a', new Path());
@@ -26,4 +24,41 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
$event = new BeforePropertyEvent('a', $path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new BeforePropertyEvent('a', $path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new BeforePropertyEvent('a', $oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new BeforePropertyEvent('a', new Path());
+ self::assertNotSame($event, $event->with());
+ }
+
+ public function testWith_GivenNoName_ResultHasOldName(): void
+ {
+ $event = new BeforePropertyEvent('a', new Path());
+ $clone = $event->with();
+ self::assertSame('a', $clone->getName());
+ }
+
+ public function testWith_GivenNewName_ResultHasNewName(): void
+ {
+ $event = new BeforePropertyEvent('a', new Path());
+ $clone = $event->with(name: 'b');
+ self::assertSame('b', $clone->getName());
+ }
}
diff --git a/tests/Event/Exception/InvalidScalarDataExceptionTest.php b/tests/Event/Exception/InvalidScalarDataExceptionTest.php
index ff50a5d..3922fc4 100644
--- a/tests/Event/Exception/InvalidScalarDataExceptionTest.php
+++ b/tests/Event/Exception/InvalidScalarDataExceptionTest.php
@@ -5,15 +5,13 @@
namespace Remorhaz\JSON\Data\Test\Event\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\Exception\InvalidScalarDataException;
-/**
- * @covers \Remorhaz\JSON\Data\Event\Exception\InvalidScalarDataException
- */
+#[CoversClass(InvalidScalarDataException::class)]
class InvalidScalarDataExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
$exception = new InvalidScalarDataException(null);
@@ -26,15 +24,9 @@ public function testGetData_ConstructedWithData_ReturnsSameValue(): void
self::assertSame('a', $exception->getData());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new InvalidScalarDataException(null);
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
- $exception = new InvalidScalarDataException(null);
+ $exception = new InvalidScalarDataException(1);
self::assertNull($exception->getPrevious());
}
diff --git a/tests/Event/ScalarEventTest.php b/tests/Event/ScalarEventTest.php
index 5c32bed..0d48ff1 100644
--- a/tests/Event/ScalarEventTest.php
+++ b/tests/Event/ScalarEventTest.php
@@ -4,35 +4,33 @@
namespace Remorhaz\JSON\Data\Test\Event;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\Exception\InvalidScalarDataException;
use Remorhaz\JSON\Data\Event\ScalarEvent;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Event\ScalarEvent
- */
+#[CoversClass(ScalarEvent::class)]
class ScalarEventTest extends TestCase
{
-
public function testConstruct_NonScalarData_ThrowsException(): void
{
$this->expectException(InvalidScalarDataException::class);
new ScalarEvent([], new Path());
}
- /**
- * @param $data
- * @param $expectedValue
- * @dataProvider providerGetData
- */
- public function testGetData_ConstructedWithScalarData_ReturnsSameValue($data, $expectedValue): void
+ #[DataProvider('providerGetData')]
+ public function testGetData_ConstructedWithScalarData_ReturnsSameValue(mixed $data, mixed $expectedValue): void
{
$event = new ScalarEvent($data, new Path());
self::assertSame($expectedValue, $event->getData());
}
- public function providerGetData(): array
+ /**
+ * @return iterable
+ */
+ public static function providerGetData(): iterable
{
return [
'Null' => [null, null],
@@ -49,4 +47,55 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
$event = new ScalarEvent(null, $path);
self::assertSame($path, $event->getPath());
}
+
+ public function testWith_GivenNoPath_ResultHasOldPath(): void
+ {
+ $path = new Path();
+ $event = new ScalarEvent(null, $path);
+ $clone = $event->with();
+ self::assertSame($path, $clone->getPath());
+ }
+
+ public function testWith_GivenNewPath_ResultHasNewPath(): void
+ {
+ $oldPath = new Path();
+ $event = new ScalarEvent(null, $oldPath);
+ $newPath = new Path();
+ $clone = $event->with(path: $newPath);
+ self::assertSame($newPath, $clone->getPath());
+ }
+
+ public function testWith_Called_ResultIsNewInstance(): void
+ {
+ $event = new ScalarEvent(null, new Path());
+ self::assertNotSame($event, $event->with());
+ }
+
+ public function testWith_GivenNoData_ResultHasOldData(): void
+ {
+ $event = new ScalarEvent('a', new Path());
+ $clone = $event->with();
+ self::assertSame('a', $clone->getData());
+ }
+
+ public function testWith_GivenNewNonNullData_ResultHasNewData(): void
+ {
+ $event = new ScalarEvent('a', new Path());
+ $clone = $event->with(data: 'b');
+ self::assertSame('b', $clone->getData());
+ }
+
+ public function testWith_GivenNewNullDataWithoutForceFlag_ResultHasOldData(): void
+ {
+ $event = new ScalarEvent('a', new Path());
+ $clone = $event->with(data: null);
+ self::assertSame('a', $clone->getData());
+ }
+
+ public function testWith_GivenNewNullDataWithForceFlag_ResultHasNewData(): void
+ {
+ $event = new ScalarEvent('a', new Path());
+ $clone = $event->with(data: null, forceData: true);
+ self::assertSame(null, $clone->getData());
+ }
}
diff --git a/tests/Export/Exception/EncodingFailedExceptionTest.php b/tests/Export/Exception/EncodingFailedExceptionTest.php
index f4c74bf..1244da1 100644
--- a/tests/Export/Exception/EncodingFailedExceptionTest.php
+++ b/tests/Export/Exception/EncodingFailedExceptionTest.php
@@ -5,15 +5,13 @@
namespace Remorhaz\JSON\Data\Test\Export\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Export\Exception\EncodingFailedException;
-/**
- * @covers \Remorhaz\JSON\Data\Export\Exception\EncodingFailedException
- */
+#[CoversClass(EncodingFailedException::class)]
class EncodingFailedExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
$exception = new EncodingFailedException('a');
@@ -26,12 +24,6 @@ public function testGetData_ConstructedWithData_ReturnsSameValue(): void
self::assertSame('a', $exception->getData());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new EncodingFailedException('a');
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new EncodingFailedException('a');
diff --git a/tests/Export/Exception/NoValueToExportExceptionTest.php b/tests/Export/Exception/NoValueToExportExceptionTest.php
index 4f595b5..fe1aa0d 100644
--- a/tests/Export/Exception/NoValueToExportExceptionTest.php
+++ b/tests/Export/Exception/NoValueToExportExceptionTest.php
@@ -5,15 +5,13 @@
namespace Remorhaz\JSON\Data\Test\Export\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Export\Exception\NoValueToExportException;
-/**
- * @covers \Remorhaz\JSON\Data\Export\Exception\NoValueToExportException
- */
+#[CoversClass(NoValueToExportException::class)]
class NoValueToExportExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
$exception = new NoValueToExportException();
diff --git a/tests/Export/Exception/UnexpectedValueExceptionTest.php b/tests/Export/Exception/UnexpectedValueExceptionTest.php
index da3ecdd..51ecbce 100644
--- a/tests/Export/Exception/UnexpectedValueExceptionTest.php
+++ b/tests/Export/Exception/UnexpectedValueExceptionTest.php
@@ -5,38 +5,30 @@
namespace Remorhaz\JSON\Data\Test\Export\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Export\Exception\UnexpectedValueException;
use Remorhaz\JSON\Data\Value\ValueInterface;
-/**
- * @covers \Remorhaz\JSON\Data\Export\Exception\UnexpectedValueException
- */
+#[CoversClass(UnexpectedValueException::class)]
class UnexpectedValueExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
- $exception = new UnexpectedValueException($this->createMock(ValueInterface::class));
+ $exception = new UnexpectedValueException(self::createStub(ValueInterface::class));
self::assertSame('Unexpected value', $exception->getMessage());
}
public function testGetValue_ConstructedWithData_ReturnsSameValue(): void
{
- $value = $this->createMock(ValueInterface::class);
+ $value = self::createStub(ValueInterface::class);
$exception = new UnexpectedValueException($value);
self::assertSame($value, $exception->getValue());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new UnexpectedValueException($this->createMock(ValueInterface::class));
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
- $exception = new UnexpectedValueException($this->createMock(ValueInterface::class));
+ $exception = new UnexpectedValueException(self::createStub(ValueInterface::class));
self::assertNull($exception->getPrevious());
}
@@ -44,7 +36,7 @@ public function testGetPrevious_ConstructedWithPrevious_ReturnsSameInstance(): v
{
$previous = new Exception();
$exception = new UnexpectedValueException(
- $this->createMock(ValueInterface::class),
+ self::createStub(ValueInterface::class),
$previous,
);
self::assertSame($previous, $exception->getPrevious());
diff --git a/tests/Export/Exception/UnknownEventExceptionTest.php b/tests/Export/Exception/UnknownEventExceptionTest.php
index cb29689..24cd99b 100644
--- a/tests/Export/Exception/UnknownEventExceptionTest.php
+++ b/tests/Export/Exception/UnknownEventExceptionTest.php
@@ -5,38 +5,30 @@
namespace Remorhaz\JSON\Data\Test\Export\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Event\EventInterface;
use Remorhaz\JSON\Data\Export\Exception\UnknownEventException;
-/**
- * @covers \Remorhaz\JSON\Data\Export\Exception\UnknownEventException
- */
+#[CoversClass(UnknownEventException::class)]
class UnknownEventExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
- $exception = new UnknownEventException($this->createMock(EventInterface::class));
+ $exception = new UnknownEventException(self::createStub(EventInterface::class));
self::assertSame('Unknown event', $exception->getMessage());
}
public function testGetEvent_ConstructedWithData_ReturnsSameValue(): void
{
- $event = $this->createMock(EventInterface::class);
+ $event = self::createStub(EventInterface::class);
$exception = new UnknownEventException($event);
self::assertSame($event, $exception->getEvent());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new UnknownEventException($this->createMock(EventInterface::class));
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
- $exception = new UnknownEventException($this->createMock(EventInterface::class));
+ $exception = new UnknownEventException(self::createStub(EventInterface::class));
self::assertNull($exception->getPrevious());
}
@@ -44,7 +36,7 @@ public function testGetPrevious_ConstructedWithPrevious_ReturnsSameInstance(): v
{
$previous = new Exception();
$exception = new UnknownEventException(
- $this->createMock(EventInterface::class),
+ self::createStub(EventInterface::class),
$previous,
);
self::assertSame($previous, $exception->getPrevious());
diff --git a/tests/Path/Exception/ParentNotFoundExceptionTest.php b/tests/Path/Exception/ParentNotFoundExceptionTest.php
index 2fac766..481558f 100644
--- a/tests/Path/Exception/ParentNotFoundExceptionTest.php
+++ b/tests/Path/Exception/ParentNotFoundExceptionTest.php
@@ -5,16 +5,15 @@
namespace Remorhaz\JSON\Data\Test\Path\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Path\Exception\ParentNotFoundException;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Path\Exception\ParentNotFoundException
- */
+#[CoversClass(ParentNotFoundException::class)]
class ParentNotFoundExceptionTest extends TestCase
{
-
public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
{
$path = new Path();
@@ -23,10 +22,10 @@ public function testGetPath_ConstructedWithPath_ReturnsSameInstance(): void
}
/**
- * @param array $pathElements
- * @param string $expectedValue
- * @dataProvider providerGetMessage
+ * @param list $pathElements
+ * @param string $expectedValue
*/
+ #[DataProvider('providerGetMessage')]
public function testGetMessage(array $pathElements, string $expectedValue): void
{
$path = new Path(...$pathElements);
@@ -34,7 +33,10 @@ public function testGetMessage(array $pathElements, string $expectedValue): void
self::assertSame($expectedValue, $exception->getMessage());
}
- public function providerGetMessage(): array
+ /**
+ * @return iterable, string}>
+ */
+ public static function providerGetMessage(): iterable
{
return [
'Empty path' => [[], "Parent not found in path /"],
@@ -42,12 +44,6 @@ public function providerGetMessage(): array
];
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new ParentNotFoundException(new Path());
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new ParentNotFoundException(new Path());
diff --git a/tests/Path/PathTest.php b/tests/Path/PathTest.php
index 6a59d0e..1bbd1e9 100644
--- a/tests/Path/PathTest.php
+++ b/tests/Path/PathTest.php
@@ -4,16 +4,15 @@
namespace Remorhaz\JSON\Data\Test\Path;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Path\Exception\ParentNotFoundException;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Path\Path
- */
+#[CoversClass(Path::class)]
class PathTest extends TestCase
{
-
public function testGetElements_ConstructedWithGivenElements_ReturnsSameValues(): void
{
$path = new Path('a', 1);
@@ -45,10 +44,10 @@ public function testCopyWithProperty_Constructed_ResultContainsMatchingElements(
}
/**
- * @param array $firstElements
- * @param array $secondElements
- * @dataProvider providerEquals
+ * @param list $firstElements
+ * @param list $secondElements
*/
+ #[DataProvider('providerEquals')]
public function testEquals_EqualPath_ReturnsTrue(array $firstElements, array $secondElements): void
{
$firstPath = new Path(...$firstElements);
@@ -57,7 +56,10 @@ public function testEquals_EqualPath_ReturnsTrue(array $firstElements, array $se
self::assertTrue($firstPath->equals($secondPath));
}
- public function providerEquals(): array
+ /**
+ * @return iterable, list}>
+ */
+ public static function providerEquals(): iterable
{
return [
'Empty paths' => [[], []],
@@ -66,10 +68,10 @@ public function providerEquals(): array
}
/**
- * @param array $firstElements
- * @param array $secondElements
- * @dataProvider providerNotEquals
+ * @param list $firstElements
+ * @param list $secondElements
*/
+ #[DataProvider('providerNotEquals')]
public function testEquals_NotEqualPath_ReturnsFalse(array $firstElements, array $secondElements): void
{
$firstPath = new Path(...$firstElements);
@@ -78,7 +80,10 @@ public function testEquals_NotEqualPath_ReturnsFalse(array $firstElements, array
self::assertFalse($firstPath->equals($secondPath));
}
- public function providerNotEquals(): array
+ /**
+ * @return iterable, list}>
+ */
+ public static function providerNotEquals(): iterable
{
return [
'Nested paths' => [['a', 1], ['a']],
@@ -87,10 +92,10 @@ public function providerNotEquals(): array
}
/**
- * @param array $pathElements
- * @param array $containedPathElements
- * @dataProvider providerContains
+ * @param list $pathElements
+ * @param list $containedPathElements
*/
+ #[DataProvider('providerContains')]
public function testContains_ContainedPath_ReturnsTrue(array $pathElements, array $containedPathElements): void
{
$path = new Path(...$pathElements);
@@ -98,7 +103,10 @@ public function testContains_ContainedPath_ReturnsTrue(array $pathElements, arra
self::assertTrue($path->contains($containedPath));
}
- public function providerContains(): array
+ /**
+ * @return iterable, list}>
+ */
+ public static function providerContains(): iterable
{
return [
'Same path' => [['a', 1], ['a', 1]],
@@ -114,10 +122,10 @@ public function testCopyParent_NonEmptyPath_ReturnsNewInstance(): void
}
/**
- * @dataProvider providerCopyExistingParent
- * @param array $pathElements
- * @param array $expectedElements
+ * @param list $pathElements
+ * @param list $expectedElements
*/
+ #[DataProvider('providerCopyExistingParent')]
public function testCopyParent_NonEmptyPath_ReturnsMatchingPath(array $pathElements, array $expectedElements): void
{
$path = new Path(...$pathElements);
@@ -125,7 +133,10 @@ public function testCopyParent_NonEmptyPath_ReturnsMatchingPath(array $pathEleme
self::assertSame($expectedElements, $pathCopy->getElements());
}
- public function providerCopyExistingParent(): array
+ /**
+ * @return iterable, list}>
+ */
+ public static function providerCopyExistingParent(): iterable
{
return [
'Single element path' => [['a'], []],
diff --git a/tests/Value/DecodedJson/Exception/InvalidElementKeyExceptionTest.php b/tests/Value/DecodedJson/Exception/InvalidElementKeyExceptionTest.php
index 0ffd3cf..8221dbb 100644
--- a/tests/Value/DecodedJson/Exception/InvalidElementKeyExceptionTest.php
+++ b/tests/Value/DecodedJson/Exception/InvalidElementKeyExceptionTest.php
@@ -5,29 +5,34 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidElementKeyException;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidElementKeyException
- */
+#[CoversClass(InvalidElementKeyException::class)]
class InvalidElementKeyExceptionTest extends TestCase
{
-
/**
- * @param $key
- * @param array $pathElements
- * @param $expectedValue
- * @dataProvider providerKeyMessage
+ * @param mixed $key
+ * @param list $pathElements
+ * @param string $expectedValue
*/
- public function testGetMessage_Constructed_ReturnsMatchingValue($key, array $pathElements, $expectedValue): void
- {
+ #[DataProvider('providerKeyMessage')]
+ public function testGetMessage_Constructed_ReturnsMatchingValue(
+ mixed $key,
+ array $pathElements,
+ string $expectedValue,
+ ): void {
$exception = new InvalidElementKeyException($key, new Path(...$pathElements));
self::assertSame($expectedValue, $exception->getMessage());
}
- public function providerKeyMessage(): array
+ /**
+ * @return iterable, string}>
+ */
+ public static function providerKeyMessage(): iterable
{
/** @noinspection HtmlUnknownTag */
return [
@@ -44,18 +49,17 @@ public function testGetPath_ConstructedWithGivenPath_ReturnsSameInstance(): void
self::assertSame($path, $exception->getPath());
}
- /**
- * @param $key
- * @param $expectedValue
- * @dataProvider providerKey
- */
- public function testGetKey_ConstructedWithGivenKey_ReturnsSameValue($key, $expectedValue): void
+ #[DataProvider('providerKey')]
+ public function testGetKey_ConstructedWithGivenKey_ReturnsSameValue(mixed $key, mixed $expectedValue): void
{
$exception = new InvalidElementKeyException($key, new Path());
self::assertSame($expectedValue, $exception->getKey());
}
- public function providerKey(): array
+ /**
+ * @return iterable
+ */
+ public static function providerKey(): iterable
{
return [
'Integer' => [1, 1],
@@ -63,12 +67,6 @@ public function providerKey(): array
];
}
- public function testGetCode_Always_ReturnZero(): void
- {
- $exception = new InvalidElementKeyException(0, new Path());
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new InvalidElementKeyException(0, new Path());
diff --git a/tests/Value/DecodedJson/Exception/InvalidNodeDataExceptionTest.php b/tests/Value/DecodedJson/Exception/InvalidNodeDataExceptionTest.php
index a64e475..36304f6 100644
--- a/tests/Value/DecodedJson/Exception/InvalidNodeDataExceptionTest.php
+++ b/tests/Value/DecodedJson/Exception/InvalidNodeDataExceptionTest.php
@@ -5,28 +5,30 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidNodeDataException;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidNodeDataException
- */
+#[CoversClass(InvalidNodeDataException::class)]
class InvalidNodeDataExceptionTest extends TestCase
{
-
/**
- * @param array $elements
- * @param $expectedValue
- * @dataProvider providerGetMessage
+ * @param list $elements
+ * @param string $expectedValue
*/
- public function testGetMessage_Constructed_ReturnsMatchingValue(array $elements, $expectedValue): void
+ #[DataProvider('providerGetMessage')]
+ public function testGetMessage_Constructed_ReturnsMatchingValue(array $elements, string $expectedValue): void
{
$exception = new InvalidNodeDataException(null, new Path(...$elements));
self::assertSame($expectedValue, $exception->getMessage());
}
- public function providerGetMessage(): array
+ /**
+ * @return iterable, string}>
+ */
+ public static function providerGetMessage(): iterable
{
return [
'Empty path' => [[], 'Invalid data in decoded JSON at /'],
@@ -48,12 +50,6 @@ public function testGetPath_ConstructedWithGivenPath_ReturnsSameInstance(): void
self::assertSame($path, $exception->getPath());
}
- public function testGetCode_Always_ReturnZero(): void
- {
- $exception = new InvalidNodeDataException(0, new Path());
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new InvalidNodeDataException(0, new Path());
diff --git a/tests/Value/DecodedJson/NodeArrayValueTest.php b/tests/Value/DecodedJson/NodeArrayValueTest.php
index 3c1e1ba..a3a35ef 100644
--- a/tests/Value/DecodedJson/NodeArrayValueTest.php
+++ b/tests/Value/DecodedJson/NodeArrayValueTest.php
@@ -4,7 +4,8 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson;
-use PHPUnit\Framework\Constraint\Callback;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use Remorhaz\JSON\Data\Path\PathInterface;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactoryInterface;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
@@ -16,16 +17,10 @@
use function iterator_to_array;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\NodeArrayValue
- */
+#[CoversClass(NodeArrayValue::class)]
class NodeArrayValueTest extends TestCase
{
-
- /**
- * @param array $data
- * @dataProvider providerArrayWithInvalidIndex
- */
+ #[DataProvider('providerArrayWithInvalidIndex')]
public function testCreateChildIterator_ArrayDataWithInvalidIndex_ThrowsException(array $data): void
{
$value = new NodeArrayValue($data, new Path(), NodeValueFactory::create());
@@ -34,7 +29,10 @@ public function testCreateChildIterator_ArrayDataWithInvalidIndex_ThrowsExceptio
iterator_to_array($value->createChildIterator(), true);
}
- public function providerArrayWithInvalidIndex(): array
+ /**
+ * @return iterable
+ */
+ public static function providerArrayWithInvalidIndex(): iterable
{
return [
'Non-zero first index' => [[1 => 'a']],
@@ -51,35 +49,35 @@ public function testCreateChildIterator_EmptyArrayData_ReturnsEmptyIterator(): v
public function testCreateChildIterator_NotEmptyArrayData_CallsFactoryForEachElement(): void
{
- $nodeValueFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $nodeValueFactory = self::createStub(NodeValueFactoryInterface::class);
$value = new NodeArrayValue(['a', 1], new Path('b'), $nodeValueFactory);
+ $interceptedArguments = [];
$nodeValueFactory
- ->expects(self::exactly(2))
->method('createValue')
- ->withConsecutive(
- [self::identicalTo('a'), $this->isArgEqualPath('b', 0)],
- [self::identicalTo(1), $this->isArgEqualPath('b', 1)],
+ ->willReturnCallback(
+ function (mixed $data, ?PathInterface $path) use (&$interceptedArguments): NodeValueInterface {
+ /** @psalm-var array $interceptedArguments */
+ $interceptedArguments[] = [$data, $path?->getElements() ?? []];
+
+ return self::createStub(NodeValueInterface::class);
+ }
);
iterator_to_array($value->createChildIterator(), true);
- }
-
- private function isArgEqualPath(...$elements): Callback
- {
- $callback = function (PathInterface $path) use ($elements): bool {
- return $path->equals(new Path(...$elements));
- };
-
- return self::callback($callback);
+ $expectedValue = [
+ ['a', ['b', 0]],
+ [1, ['b', 1]],
+ ];
+ self::assertSame($expectedValue, $interceptedArguments);
}
public function testCreateChildIterator_NodeFactoryReturnsValues_ReturnsSameValuesWithMatchingIndexes(): void
{
- $nodeValueFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $nodeValueFactory = self::createStub(NodeValueFactoryInterface::class);
$value = new NodeArrayValue(['a', 1], new Path('b'), $nodeValueFactory);
- $firstNode = $this->createMock(NodeValueInterface::class);
- $secondNode = $this->createMock(NodeValueInterface::class);
+ $firstNode = self::createStub(NodeValueInterface::class);
+ $secondNode = self::createStub(NodeValueInterface::class);
$nodeValueFactory
->method('createValue')
->willReturnOnConsecutiveCalls($firstNode, $secondNode);
diff --git a/tests/Value/DecodedJson/NodeObjectValueTest.php b/tests/Value/DecodedJson/NodeObjectValueTest.php
index 55bae3c..829f0c9 100644
--- a/tests/Value/DecodedJson/NodeObjectValueTest.php
+++ b/tests/Value/DecodedJson/NodeObjectValueTest.php
@@ -4,7 +4,7 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson;
-use PHPUnit\Framework\Constraint\Callback;
+use PHPUnit\Framework\Attributes\CoversClass;
use Remorhaz\JSON\Data\Path\PathInterface;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeObjectValue;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactoryInterface;
@@ -15,12 +15,9 @@
use function iterator_to_array;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\NodeObjectValue
- */
+#[CoversClass(NodeObjectValue::class)]
class NodeObjectValueTest extends TestCase
{
-
public function testCreateChildIterator_EmptyObjectData_ReturnsEmptyIterator(): void
{
$value = new NodeObjectValue((object) [], new Path(), NodeValueFactory::create());
@@ -30,35 +27,35 @@ public function testCreateChildIterator_EmptyObjectData_ReturnsEmptyIterator():
public function testCreateChildIterator_NotEmptyObjectData_CallsFactoryForEachElement(): void
{
- $nodeValueFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $nodeValueFactory = self::createStub(NodeValueFactoryInterface::class);
$value = new NodeObjectValue((object) ['a' => 'b', 'c' => 1], new Path('d'), $nodeValueFactory);
+ $interceptedArgs = [];
$nodeValueFactory
- ->expects(self::exactly(2))
->method('createValue')
- ->withConsecutive(
- [self::identicalTo('b'), $this->isArgEqualPath('d', 'a')],
- [self::identicalTo(1), $this->isArgEqualPath('d', 'c')],
+ ->willReturnCallback(
+ function (mixed $data, ?PathInterface $path) use (&$interceptedArgs): NodeValueInterface {
+ /** @psalm-var array $interceptedArgs */
+ $interceptedArgs[] = [$data, $path?->getElements() ?? []];
+
+ return self::createStub(NodeValueInterface::class);
+ },
);
iterator_to_array($value->createChildIterator(), true);
- }
-
- private function isArgEqualPath(...$elements): Callback
- {
- $callback = function (PathInterface $path) use ($elements): bool {
- return $path->equals(new Path(...$elements));
- };
-
- return self::callback($callback);
+ $expectedValue = [
+ ['b', ['d', 'a']],
+ [1, ['d', 'c']],
+ ];
+ self::assertSame($expectedValue, $interceptedArgs);
}
public function testCreateChildIterator_NodeFactoryReturnsValues_ReturnsSameValuesWithMatchingIndexes(): void
{
- $nodeValueFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $nodeValueFactory = self::createStub(NodeValueFactoryInterface::class);
$value = new NodeObjectValue((object) ['a' => 'b', 'c' => 1], new Path('d'), $nodeValueFactory);
- $firstNode = $this->createMock(NodeValueInterface::class);
- $secondNode = $this->createMock(NodeValueInterface::class);
+ $firstNode = self::createStub(NodeValueInterface::class);
+ $secondNode = self::createStub(NodeValueInterface::class);
$nodeValueFactory
->method('createValue')
->willReturnOnConsecutiveCalls($firstNode, $secondNode);
diff --git a/tests/Value/DecodedJson/NodeScalarValueTest.php b/tests/Value/DecodedJson/NodeScalarValueTest.php
index e0b7239..6e5d993 100644
--- a/tests/Value/DecodedJson/NodeScalarValueTest.php
+++ b/tests/Value/DecodedJson/NodeScalarValueTest.php
@@ -4,28 +4,27 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeScalarValue;
use Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidNodeDataException;
use Remorhaz\JSON\Data\Path\Path;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\NodeScalarValue
- */
+#[CoversClass(NodeScalarValue::class)]
class NodeScalarValueTest extends TestCase
{
-
- /**
- * @param $data
- * @dataProvider providerInvalidData
- */
- public function testConstruct_InvalidData_ThrowsMatchingException($data): void
+ #[DataProvider('providerInvalidData')]
+ public function testConstruct_InvalidData_ThrowsMatchingException(mixed $data): void
{
$this->expectException(InvalidNodeDataException::class);
new NodeScalarValue($data, new Path());
}
- public function providerInvalidData(): array
+ /**
+ * @return iterable
+ */
+ public static function providerInvalidData(): iterable
{
return [
'Resource' => [STDERR],
diff --git a/tests/Value/DecodedJson/NodeValueFactoryTest.php b/tests/Value/DecodedJson/NodeValueFactoryTest.php
index 3f21594..8385f6d 100644
--- a/tests/Value/DecodedJson/NodeValueFactoryTest.php
+++ b/tests/Value/DecodedJson/NodeValueFactoryTest.php
@@ -4,6 +4,8 @@
namespace Remorhaz\JSON\Data\Test\Value\DecodedJson;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Value\DecodedJson\Exception\InvalidNodeDataException;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeArrayValue;
@@ -15,23 +17,20 @@
use const STDOUT;
-/**
- * @covers \Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactory
- */
+#[CoversClass(NodeValueFactory::class)]
class NodeValueFactoryTest extends TestCase
{
-
- /**
- * @param mixed $data
- * @dataProvider providerScalarDataOrNull
- */
- public function testCreateValue_ScalarDataOrNull_ReturnsNodeScalarValue($data): void
+ #[DataProvider('providerScalarDataOrNull')]
+ public function testCreateValue_ScalarDataOrNull_ReturnsNodeScalarValue(mixed $data): void
{
$actualValue = NodeValueFactory::create()->createValue($data, new Path());
self::assertInstanceOf(NodeScalarValue::class, $actualValue);
}
- public function providerScalarDataOrNull(): array
+ /**
+ * @return iterable
+ */
+ public static function providerScalarDataOrNull(): iterable
{
return [
'Null' => [null, null],
@@ -42,33 +41,23 @@ public function providerScalarDataOrNull(): array
];
}
- /**
- * @param mixed $data
- * @dataProvider providerScalarDataOrNull
- */
- public function testCreateValue_ScalarValueAndGivenPath_ResultHasSamePathInstance($data): void
+ #[DataProvider('providerScalarDataOrNull')]
+ public function testCreateValue_ScalarValueAndGivenPath_ResultHasSamePathInstance(mixed $data): void
{
$path = new Path();
$actualValue = NodeValueFactory::create()->createValue($data, $path);
self::assertSame($path, $actualValue->getPath());
}
- /**
- * @param mixed $data
- * @dataProvider providerScalarDataOrNull
- */
- public function testCreateValue_ScalarValueAndNoPath_ResultHasEmptyPath($data): void
+ #[DataProvider('providerScalarDataOrNull')]
+ public function testCreateValue_ScalarValueAndNoPath_ResultHasEmptyPath(mixed $data): void
{
$actualValue = NodeValueFactory::create()->createValue($data);
self::assertEmpty($actualValue->getPath()->getElements());
}
- /**
- * @param mixed $data
- * @param $expectedValue
- * @dataProvider providerScalarDataOrNull
- */
- public function testCreateValue_ScalarValue_ResultHasMatchingData($data, $expectedValue): void
+ #[DataProvider('providerScalarDataOrNull')]
+ public function testCreateValue_ScalarValue_ResultHasMatchingData(mixed $data, mixed $expectedValue): void
{
$path = new Path();
/** @var ScalarValueInterface $actualValue */
@@ -120,11 +109,4 @@ public function testCreateValue_NonScalarValue_ThrowsException(): void
$this->expectException(InvalidNodeDataException::class);
$factory->createValue(STDOUT, new Path());
}
-
- public function testCreateValue_NonMatchingObject_ThrowsException(): void
- {
- $factory = NodeValueFactory::create();
- $this->expectException(InvalidNodeDataException::class);
- $factory->createValue(new Path(), new Path());
- }
}
diff --git a/tests/Value/EncodedJson/Exception/JsonNotDecodedExceptionTest.php b/tests/Value/EncodedJson/Exception/JsonNotDecodedExceptionTest.php
index b70331a..c339188 100644
--- a/tests/Value/EncodedJson/Exception/JsonNotDecodedExceptionTest.php
+++ b/tests/Value/EncodedJson/Exception/JsonNotDecodedExceptionTest.php
@@ -5,15 +5,13 @@
namespace Remorhaz\JSON\Data\Test\Value\EncodedJson\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Value\EncodedJson\Exception\JsonNotDecodedException;
-/**
- * @covers \Remorhaz\JSON\Data\Value\EncodedJson\Exception\JsonNotDecodedException
- */
+#[CoversClass(JsonNotDecodedException::class)]
class JsonNotDecodedExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
$exception = new JsonNotDecodedException('a');
@@ -26,12 +24,6 @@ public function testGetJson_ConstructedWithJson_ReturnsSameValue(): void
self::assertSame('a', $exception->getJson());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new JsonNotDecodedException('a');
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new JsonNotDecodedException('a');
diff --git a/tests/Value/EncodedJson/NodeValueFactoryTest.php b/tests/Value/EncodedJson/NodeValueFactoryTest.php
index c5d4d8d..27a3edf 100644
--- a/tests/Value/EncodedJson/NodeValueFactoryTest.php
+++ b/tests/Value/EncodedJson/NodeValueFactoryTest.php
@@ -4,6 +4,7 @@
namespace Remorhaz\JSON\Data\Test\Value\EncodedJson;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Path\Path;
use Remorhaz\JSON\Data\Value\DecodedJson\NodeValueFactoryInterface;
@@ -11,12 +12,9 @@
use Remorhaz\JSON\Data\Value\EncodedJson\NodeValueFactory;
use Remorhaz\JSON\Data\Value\NodeValueInterface;
-/**
- * @covers \Remorhaz\JSON\Data\Value\EncodedJson\NodeValueFactory
- */
+#[CoversClass(NodeValueFactory::class)]
class NodeValueFactoryTest extends TestCase
{
-
public function testCreate_Always_ReturnsNodeValueInstance(): void
{
self::assertInstanceOf(NodeValueFactory::class, NodeValueFactory::create());
@@ -31,7 +29,7 @@ public function testCreateValue_InvalidJson_ThrowsException(): void
public function testCreateValue_ValidJsonNoPath_PassesDecodedJsonAndNullToDecodedJsonFactory(): void
{
- $decodedJsonFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $decodedJsonFactory = self::createMock(NodeValueFactoryInterface::class);
$encodedJsonFactory = new NodeValueFactory($decodedJsonFactory);
$decodedJsonFactory
@@ -43,7 +41,7 @@ public function testCreateValue_ValidJsonNoPath_PassesDecodedJsonAndNullToDecode
public function testCreateValue_ValidJsonWithPath_PassesDecodedJsonAndSamePathInstanceToDecodedJsonFactory(): void
{
- $decodedJsonFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $decodedJsonFactory = self::createMock(NodeValueFactoryInterface::class);
$encodedJsonFactory = new NodeValueFactory($decodedJsonFactory);
$path = new Path();
@@ -56,10 +54,10 @@ public function testCreateValue_ValidJsonWithPath_PassesDecodedJsonAndSamePathIn
public function testCreateValue_DecodedJsonFactoryReturnsInstanceReturnsSameInstance(): void
{
- $decodedJsonFactory = $this->createMock(NodeValueFactoryInterface::class);
+ $decodedJsonFactory = self::createStub(NodeValueFactoryInterface::class);
$encodedJsonFactory = new NodeValueFactory($decodedJsonFactory);
- $nodeValue = $this->createMock(NodeValueInterface::class);
+ $nodeValue = self::createStub(NodeValueInterface::class);
$decodedJsonFactory
->method('createValue')
->willReturn($nodeValue);
diff --git a/tests/Walker/EventGeneratorTest.php b/tests/Walker/EventGeneratorTest.php
new file mode 100644
index 0000000..72ad95e
--- /dev/null
+++ b/tests/Walker/EventGeneratorTest.php
@@ -0,0 +1,180 @@
+ $expectedEvents
+ */
+ #[DataProvider('providerValueEvents')]
+ public function testInvoke_ConstructedWithValue_IteratesMatchingEvents(mixed $value, array $expectedEvents): void
+ {
+ $nodeFactory = new NodeValueFactory();
+ $value = $nodeFactory->createValue($value, new Path(1));
+ $generator = new EventGenerator($value, new Path(2));
+ $events = iterator_to_array($generator(), false);
+ self::assertSame($expectedEvents, $this->exportEvents(...$events));
+ }
+
+ /**
+ * @return iterable}>
+ */
+ public static function providerValueEvents(): iterable
+ {
+ return [
+ 'Scalar value' => [
+ 'a',
+ [
+ [
+ 'class' => ScalarEvent::class,
+ 'path' => [2],
+ 'data' => 'a',
+ ],
+ ],
+ ],
+ 'Array with two scalars' => [
+ ['a', 'b'],
+ [
+ [
+ 'class' => BeforeArrayEvent::class,
+ 'path' => [2],
+ ],
+ [
+ 'class' => BeforeElementEvent::class,
+ 'path' => [2, 0],
+ 'index' => 0,
+ ],
+ [
+ 'class' => ScalarEvent::class,
+ 'path' => [2, 0],
+ 'data' => 'a',
+ ],
+ [
+ 'class' => AfterElementEvent::class,
+ 'path' => [2, 0],
+ 'index' => 0,
+ ],
+ [
+ 'class' => BeforeElementEvent::class,
+ 'path' => [2, 1],
+ 'index' => 1,
+ ],
+ [
+ 'class' => ScalarEvent::class,
+ 'path' => [2, 1],
+ 'data' => 'b',
+ ],
+ [
+ 'class' => AfterElementEvent::class,
+ 'path' => [2, 1],
+ 'index' => 1,
+ ],
+ [
+ 'class' => AfterArrayEvent::class,
+ 'path' => [2],
+ ],
+ ],
+ ],
+ 'Object with two properties' => [
+ (object) ['a' => 'b', 'c' => 'd'],
+ [
+ [
+ 'class' => BeforeObjectEvent::class,
+ 'path' => [2],
+ ],
+ [
+ 'class' => BeforePropertyEvent::class,
+ 'path' => [2, 'a'],
+ 'name' => 'a',
+ ],
+ [
+ 'class' => ScalarEvent::class,
+ 'path' => [2, 'a'],
+ 'data' => 'b',
+ ],
+ [
+ 'class' => AfterPropertyEvent::class,
+ 'path' => [2, 'a'],
+ 'name' => 'a',
+ ],
+ [
+ 'class' => BeforePropertyEvent::class,
+ 'path' => [2, 'c'],
+ 'name' => 'c',
+ ],
+ [
+ 'class' => ScalarEvent::class,
+ 'path' => [2, 'c'],
+ 'data' => 'd',
+ ],
+ [
+ 'class' => AfterPropertyEvent::class,
+ 'path' => [2, 'c'],
+ 'name' => 'c',
+ ],
+ [
+ 'class' => AfterObjectEvent::class,
+ 'path' => [2],
+ ],
+ ],
+ ],
+ ];
+ }
+
+ private function exportEvents(EventInterface ...$events): array
+ {
+ return array_map($this->exportEvent(...), $events);
+ }
+
+ private function exportEvent(EventInterface $event): array
+ {
+ return [
+ 'class' => $event::class,
+ 'path' => $event->getPath()->getElements(),
+ ...match (true) {
+ $event instanceof ScalarEventInterface => ['data' => $event->getData()],
+ $event instanceof ElementEventInterface => ['index' => $event->getIndex()],
+ $event instanceof PropertyEventInterface => ['name' => $event->getName()],
+ default => [],
+ },
+ ];
+ }
+
+ public function testInvoke_ConstructedWithInvalidValue_ThrowsException(): void
+ {
+ $value = self::createStub(NodeValueInterface::class);
+ $generator = new EventGenerator($value, new Path());
+ $this->expectException(UnexpectedEntityException::class);
+ iterator_to_array($generator());
+ }
+}
diff --git a/tests/Walker/Exception/UnexpectedEntityExceptionTest.php b/tests/Walker/Exception/UnexpectedEntityExceptionTest.php
index 5d041b5..5049e16 100644
--- a/tests/Walker/Exception/UnexpectedEntityExceptionTest.php
+++ b/tests/Walker/Exception/UnexpectedEntityExceptionTest.php
@@ -5,15 +5,13 @@
namespace Remorhaz\JSON\Data\Test\Walker\Exception;
use Exception;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Remorhaz\JSON\Data\Walker\Exception\UnexpectedEntityException;
-/**
- * @covers \Remorhaz\JSON\Data\Walker\Exception\UnexpectedEntityException
- */
+#[CoversClass(UnexpectedEntityException::class)]
class UnexpectedEntityExceptionTest extends TestCase
{
-
public function testGetMessage_Constructed_ReturnsMatchingValue(): void
{
$exception = new UnexpectedEntityException('a');
@@ -26,12 +24,6 @@ public function testGetEntity_ConstructedWithEntity_ReturnsSameValue(): void
self::assertSame('a', $exception->getEntity());
}
- public function testGetCode_Always_ReturnsZero(): void
- {
- $exception = new UnexpectedEntityException('a');
- self::assertSame(0, $exception->getCode());
- }
-
public function testGetPrevious_ConstructedWithoutPrevious_ReturnsNull(): void
{
$exception = new UnexpectedEntityException('a');
diff --git a/vendor-bin/cs/composer.json b/vendor-bin/cs/composer.json
new file mode 100644
index 0000000..31bfe6e
--- /dev/null
+++ b/vendor-bin/cs/composer.json
@@ -0,0 +1,5 @@
+{
+ "require-dev": {
+ "squizlabs/php_codesniffer": "^3.8"
+ }
+}
diff --git a/vendor-bin/psalm/composer.json b/vendor-bin/psalm/composer.json
new file mode 100644
index 0000000..83fd035
--- /dev/null
+++ b/vendor-bin/psalm/composer.json
@@ -0,0 +1,9 @@
+{
+ "require-dev": {
+ "vimeo/psalm": "^5.21.1",
+ "psalm/plugin-phpunit": "^0.18.4"
+ },
+ "conflict": {
+ "netresearch/jsonmapper": "<4.4.1"
+ }
+}