diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 3b763a78..d1f47380 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -21,22 +21,14 @@ jobs: strategy: fail-fast: false matrix: - php-version: - - "7.2" - - "7.3" - - "7.4" - - "8.0" - - "8.1" - - "8.2" - - "8.3" - - "8.4" + php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] dependencies: [highest] include: - php-version: "7.2" dependencies: lowest -# - php-version: "8.5" -# dependencies: highest -# experimental: true + - php-version: "8.5" + dependencies: ignore + experimental: true steps: - name: "Checkout" diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d509ec..1d7b311d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- ### Changed +- ci: Add PHP 8.5 to pipeline, ignoring dependencies and as experimental ([#842](https://github.com/jsonrainbow/json-schema/pull/842)) ## [6.5.0] - 2025-08-29 ### Changed diff --git a/src/JsonSchema/Uri/Retrievers/Curl.php b/src/JsonSchema/Uri/Retrievers/Curl.php index 116607ae..311f1d34 100644 --- a/src/JsonSchema/Uri/Retrievers/Curl.php +++ b/src/JsonSchema/Uri/Retrievers/Curl.php @@ -53,7 +53,9 @@ public function retrieve($uri) $this->fetchMessageBody($response); $this->fetchContentType($response); - curl_close($ch); + if (PHP_VERSION_ID < 80000) { + curl_close($ch); + } return $this->messageBody; } diff --git a/src/JsonSchema/Uri/Retrievers/FileGetContents.php b/src/JsonSchema/Uri/Retrievers/FileGetContents.php index cfb28d6f..a4f96593 100644 --- a/src/JsonSchema/Uri/Retrievers/FileGetContents.php +++ b/src/JsonSchema/Uri/Retrievers/FileGetContents.php @@ -51,17 +51,19 @@ public function retrieve($uri) } $this->messageBody = $response; + if (function_exists('http_get_last_response_headers')) { - // Use http_get_last_response_headers() for BC compatibility with PHP 8.5+ + // Use http_get_last_response_headers() for compatibility with PHP 8.5+ // where $http_response_header is deprecated. - $http_response_header = http_get_last_response_headers(); + $httpResponseHeaders = http_get_last_response_headers(); + } else { + /** @phpstan-ignore nullCoalesce.variable ($http_response_header can non-existing when no http request was done) */ + $httpResponseHeaders = $http_response_header ?? []; } - if (!empty($http_response_header)) { - // $http_response_header cannot be tested, because it's defined in the method's local scope - // See http://php.net/manual/en/reserved.variables.httpresponseheader.php for more info. - $this->fetchContentType($http_response_header); // @codeCoverageIgnore - } else { // @codeCoverageIgnore - // Could be a "file://" url or something else - fake up the response + + if (!empty($httpResponseHeaders)) { + $this->fetchContentType($httpResponseHeaders); + } else { $this->contentType = null; } @@ -73,7 +75,7 @@ public function retrieve($uri) * * @return bool Whether the Content-Type header was found or not */ - private function fetchContentType(array $headers) + private function fetchContentType(array $headers): bool { foreach (array_reverse($headers) as $header) { if ($this->contentType = self::getContentTypeMatchInHeader($header)) { diff --git a/tests/Constraints/TypeTest.php b/tests/Constraints/TypeTest.php index 0aa830cb..8292b9b7 100644 --- a/tests/Constraints/TypeTest.php +++ b/tests/Constraints/TypeTest.php @@ -96,7 +96,9 @@ public function testValidateTypeNameWording($nameWording): void $t = new TypeConstraint(); $r = new \ReflectionObject($t); $m = $r->getMethod('validateTypeNameWording'); - $m->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $m->setAccessible(true); + } $m->invoke($t, $nameWording); $this->expectNotToPerformAssertions(); @@ -107,7 +109,9 @@ public function testInvalidateTypeNameWording(): void $t = new TypeConstraint(); $r = new \ReflectionObject($t); $m = $r->getMethod('validateTypeNameWording'); - $m->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $m->setAccessible(true); + } $this->expectException('\UnexpectedValueException'); $this->expectExceptionMessage("No wording for 'notAValidTypeName' available, expected wordings are: [an integer, a number, a boolean, an object, an array, a string, a null]"); diff --git a/tests/SchemaStorageTest.php b/tests/SchemaStorageTest.php index 502a5821..942aa43b 100644 --- a/tests/SchemaStorageTest.php +++ b/tests/SchemaStorageTest.php @@ -290,11 +290,13 @@ public function testNoDoubleResolve(): void $uriRetriever->retrieve('test/schema')->willReturn($schemaOne)->shouldBeCalled(); $s = new SchemaStorage($uriRetriever->reveal()); - $schema = $s->addSchema('test/schema'); + $s->addSchema('test/schema'); $r = new \ReflectionObject($s); $p = $r->getProperty('schemas'); - $p->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $p->setAccessible(true); + } $schemas = $p->getValue($s); $this->assertEquals( diff --git a/tests/Uri/Retrievers/FileGetContentsTest.php b/tests/Uri/Retrievers/FileGetContentsTest.php index d48d7945..70effd7c 100644 --- a/tests/Uri/Retrievers/FileGetContentsTest.php +++ b/tests/Uri/Retrievers/FileGetContentsTest.php @@ -31,7 +31,9 @@ public function testContentType(): void $reflector = new \ReflectionObject($res); $fetchContentType = $reflector->getMethod('fetchContentType'); - $fetchContentType->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $fetchContentType->setAccessible(true); + } $this->assertTrue($fetchContentType->invoke($res, ['Content-Type: application/json'])); $this->assertFalse($fetchContentType->invoke($res, ['X-Some-Header: whateverValue'])); diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index 0016cc4a..9d41b3c8 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -267,11 +267,15 @@ private function mockRetriever($schema): void $retrieverMock = $this->getRetrieverMock($schema); $factory = new \ReflectionProperty(\JsonSchema\Constraints\BaseConstraint::class, 'factory'); - $factory->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $factory->setAccessible(true); + } $factory = $factory->getValue($this->validator); $retriever = new \ReflectionProperty(\JsonSchema\Constraints\Factory::class, 'uriRetriever'); - $retriever->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $retriever->setAccessible(true); + } $retriever->setValue($factory, $retrieverMock); } @@ -362,12 +366,16 @@ public function testSchemaCache(): void // inject a schema cache value $schemaCache = $reflector->getProperty('schemaCache'); - $schemaCache->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $schemaCache->setAccessible(true); + } $schemaCache->setValue($retriever, ['local://test/uri' => 'testSchemaValue']); // retrieve from schema cache $loadSchema = $reflector->getMethod('loadSchema'); - $loadSchema->setAccessible(true); + if (PHP_VERSION_ID < 80100) { + $loadSchema->setAccessible(true); + } $this->assertEquals( 'testSchemaValue', $loadSchema->invoke($retriever, 'local://test/uri')