diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index c362142..f970da5 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -67,7 +67,7 @@ jobs:
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Upload coverage file"
- uses: "actions/upload-artifact@v2"
+ uses: "actions/upload-artifact@v4"
with:
name: "phpunit-${{ matrix.php-version }}-${{ matrix.dependencies }}-${{ matrix.dbal-version }}.coverage"
path: "coverage.xml"
diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index 39335a6..b188595 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -12,14 +12,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Validate composer.json and composer.lock
run: composer validate --strict
- name: Cache Composer packages
id: composer-cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
deleted file mode 100644
index 4a3f43c..0000000
--- a/.github/workflows/static-analysis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: "Static analysis"
-
-on:
- pull_request:
- branches:
- - "*.x"
- - "main"
- push:
- branches:
- - "*.x"
- - "main"
-
-jobs:
- psalm:
- name: "Static Analysis"
- runs-on: ubuntu-latest
-
- steps:
- - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
- with:
- php-version: '8.1'
- - uses: actions/checkout@v2
- - name: Install Dependencies
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- - name: Execute tests (Unit and Feature tests) via PHPUnit
- run: vendor/bin/psalm
diff --git a/.gitignore b/.gitignore
index 89d0f12..d4950c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ composer.lock
/.phpcs-cache
/coverage/
/.phpunit.cache/
+.phpunit.result.cache
diff --git a/composer.json b/composer.json
index aaf7fc2..c8cb178 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,17 @@
"source": "https://github.com/api-skeletons/laravel-api-problem",
"chat": "https://gitter.im/API-Skeletons/open-source"
},
+ "require": {
+ "php": "^8.1",
+ "doctrine/instantiator": "^2.0",
+ "laravel/framework": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^12.0",
+ "orchestra/testbench": "^v10.1",
+ "php-parallel-lint/php-parallel-lint": "^1.4",
+ "phpunit/phpunit": "^11.5"
+ },
"config": {
"sort-packages": true,
"allow-plugins": {
@@ -48,20 +59,7 @@
"test": [
"vendor/bin/parallel-lint src test",
"vendor/bin/phpcs",
- "vendor/bin/psalm",
"vendor/bin/phpunit"
]
- },
- "require": {
- "php": "^8.1",
- "doctrine/instantiator": "^2.0",
- "laravel/framework": "^8.0 || ^9.0 || ^10.0 || ^11.0"
- },
- "require-dev": {
- "doctrine/coding-standard": "^12.0",
- "orchestra/testbench": "^7.41",
- "php-parallel-lint/php-parallel-lint": "^1.4",
- "phpunit/phpunit": "^9.5",
- "vimeo/psalm": "^4.15"
}
}
diff --git a/psalm.xml b/psalm.xml
deleted file mode 100644
index 7c0333d..0000000
--- a/psalm.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/test/ApiProblemTest.php b/test/ApiProblemTest.php
index 476c2a1..71190f6 100644
--- a/test/ApiProblemTest.php
+++ b/test/ApiProblemTest.php
@@ -7,7 +7,6 @@
use ApiSkeletons\Laravel\ApiProblem\ApiProblem;
use ApiSkeletons\Laravel\ApiProblem\Exception;
use ApiSkeletons\Laravel\ApiProblem\Facades\ApiProblem as ApiProblemFacade;
-use http\Exception\InvalidArgumentException;
use Illuminate\Http\JsonResponse;
use ReflectionObject;
use TypeError;
@@ -15,7 +14,7 @@
final class ApiProblemTest extends TestCase
{
/** @psalm-return array */
- public function statusCodes(): array
+ public static function statusCodes(): array
{
return [
'200' => [200],
@@ -42,25 +41,21 @@ public function testResponseWithFacade(): void
$this->assertInstanceOf(JsonResponse::class, ApiProblemFacade::response('Testing', 500));
}
- /**
- * @dataProvider statusCodes
- */
+ /** @dataProvider statusCodes */
public function testStatusIsUsedVerbatim(int $status): void
{
$apiProblem = new ApiProblem($status, 'foo');
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('status', $payload);
$this->assertEquals($status, $payload['status']);
}
- /**
- * @requires PHP 7.0
- */
+ /** @requires PHP 7.0 */
public function testErrorAsDetails(): void
{
- $error = new TypeError('error message', 705);
+ $error = new TypeError('error message', 705);
$apiProblem = new ApiProblem(500, $error);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('title', $payload);
$this->assertEquals('TypeError', $payload['title']);
@@ -72,9 +67,9 @@ public function testErrorAsDetails(): void
public function testExceptionCodeIsUsedForStatus(): void
{
- $exception = new \Exception('exception message', 401);
+ $exception = new \Exception('exception message', 401);
$apiProblem = new ApiProblem('500', $exception);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('status', $payload);
$this->assertEquals($exception->getCode(), $payload['status']);
}
@@ -82,23 +77,23 @@ public function testExceptionCodeIsUsedForStatus(): void
public function testDetailStringIsUsedVerbatim(): void
{
$apiProblem = new ApiProblem('500', 'foo');
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('detail', $payload);
$this->assertEquals('foo', $payload['detail']);
}
public function testExceptionMessageIsUsedForDetail(): void
{
- $exception = new \Exception('exception message');
+ $exception = new \Exception('exception message');
$apiProblem = new ApiProblem('500', $exception);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('detail', $payload);
$this->assertEquals($exception->getMessage(), $payload['detail']);
}
public function testExceptionsCanTriggerInclusionOfStackTraceInDetails(): void
{
- $exception = new \Exception('exception message');
+ $exception = new \Exception('exception message');
$apiProblem = new ApiProblem('500', $exception);
$apiProblem->setDetailIncludesStackTrace(true);
$payload = $apiProblem->toArray();
@@ -109,7 +104,7 @@ public function testExceptionsCanTriggerInclusionOfStackTraceInDetails(): void
public function testExceptionsCanTriggerInclusionOfNestedExceptions(): void
{
- $exceptionChild = new \Exception('child exception');
+ $exceptionChild = new \Exception('child exception');
$exceptionParent = new \Exception('parent exception', 0, $exceptionChild);
$apiProblem = new ApiProblem('500', $exceptionParent);
@@ -130,13 +125,13 @@ public function testExceptionsCanTriggerInclusionOfNestedExceptions(): void
public function testTypeUrlIsUsedVerbatim(): void
{
$apiProblem = new ApiProblem('500', 'foo', 'http://status.dev:8080/details.md');
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('type', $payload);
$this->assertEquals('http://status.dev:8080/details.md', $payload['type']);
}
/** @psalm-return array */
- public function knownStatusCodes(): array
+ public static function knownStatusCodes(): array
{
return [
'404' => [404],
@@ -146,14 +141,12 @@ public function knownStatusCodes(): array
];
}
- /**
- * @dataProvider knownStatusCodes
- */
+ /** @dataProvider knownStatusCodes */
public function testKnownStatusResultsInKnownTitle(int $status): void
{
$apiProblem = new ApiProblem($status, 'foo');
- $r = new ReflectionObject($apiProblem);
- $p = $r->getProperty('problemStatusTitles');
+ $r = new ReflectionObject($apiProblem);
+ $p = $r->getProperty('problemStatusTitles');
$p->setAccessible(true);
$titles = $p->getValue($apiProblem);
@@ -165,7 +158,7 @@ public function testKnownStatusResultsInKnownTitle(int $status): void
public function testUnknownStatusResultsInUnknownTitle(): void
{
$apiProblem = new ApiProblem(420, 'foo');
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('title', $payload);
$this->assertEquals('Unknown', $payload['title']);
}
@@ -173,7 +166,7 @@ public function testUnknownStatusResultsInUnknownTitle(): void
public function testProvidedTitleIsUsedVerbatim(): void
{
$apiProblem = new ApiProblem('500', 'foo', 'http://status.dev:8080/details.md', 'some title');
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('title', $payload);
$this->assertEquals('some title', $payload['title']);
}
@@ -185,7 +178,7 @@ public function testCanPassArbitraryDetailsToConstructor(): void
'Invalid input',
'http://example.com/api/problem/400',
'Invalid entity',
- ['foo' => 'bar']
+ ['foo' => 'bar'],
);
$this->assertEquals('bar', $problem->foo);
}
@@ -197,9 +190,9 @@ public function testArraySerializationIncludesArbitraryDetails(): void
'Invalid input',
'http://example.com/api/problem/400',
'Invalid entity',
- ['foo' => 'bar']
+ ['foo' => 'bar'],
);
- $array = $problem->toArray();
+ $array = $problem->toArray();
$this->assertArrayHasKey('foo', $array);
$this->assertEquals('bar', $array['foo']);
}
@@ -211,9 +204,9 @@ public function testArbitraryDetailsShouldNotOverwriteRequiredFieldsInArraySeria
'Invalid input',
'http://example.com/api/problem/400',
'Invalid entity',
- ['title' => 'SHOULD NOT GET THIS']
+ ['title' => 'SHOULD NOT GET THIS'],
);
- $array = $problem->toArray();
+ $array = $problem->toArray();
$this->assertArrayHasKey('title', $array);
$this->assertEquals('Invalid entity', $array['title']);
}
@@ -223,7 +216,7 @@ public function testUsesTitleFromExceptionWhenProvided(): void
$exception = new Exception\DomainException('exception message', 401);
$exception->setTitle('problem title');
$apiProblem = new ApiProblem('401', $exception);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('title', $payload);
$this->assertEquals($exception->getTitle(), $payload['title']);
}
@@ -233,7 +226,7 @@ public function testUsesTypeFromExceptionWhenProvided(): void
$exception = new Exception\DomainException('exception message', 401);
$exception->setType('http://example.com/api/help/401');
$apiProblem = new ApiProblem('401', $exception);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('type', $payload);
$this->assertEquals($exception->getType(), $payload['type']);
}
@@ -243,13 +236,13 @@ public function testUsesAdditionalDetailsFromExceptionWhenProvided(): void
$exception = new Exception\DomainException('exception message', 401);
$exception->setAdditionalDetails(['foo' => 'bar']);
$apiProblem = new ApiProblem('401', $exception);
- $payload = $apiProblem->toArray();
+ $payload = $apiProblem->toArray();
$this->assertArrayHasKey('foo', $payload);
$this->assertEquals('bar', $payload['foo']);
}
/** @psalm-return array */
- public function invalidStatusCodes(): array
+ public static function invalidStatusCodes(): array
{
return [
'-1' => [-1],
@@ -266,7 +259,7 @@ public function invalidStatusCodes(): array
*/
public function testInvalidHttpStatusCodesAreCastTo500(int $code): void
{
- $e = new \Exception('Testing', $code);
+ $e = new \Exception('Testing', $code);
$problem = new ApiProblem($code, $e);
$this->assertEquals(500, $problem->status);
}