diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..cd83e0a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: test +on: + pull_request: + paths: + - "**.php" + +jobs: + test: + runs-on: ubuntu-latest + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + + - name: Setup Composer + uses: ramsey/composer-install@v3 + with: + composer-options: "--no-scripts" + + - name: Run phpunit + run: ./vendor/bin/phpunit diff --git a/examples/bootstrap_examples.php b/examples/bootstrap_examples.php index 36a7c36..33abef7 100644 --- a/examples/bootstrap_examples.php +++ b/examples/bootstrap_examples.php @@ -3,9 +3,12 @@ use alsvanzelf\jsonapi\Document; use alsvanzelf\jsonapi\ResourceDocument; use alsvanzelf\jsonapi\interfaces\ExtensionInterface; +use alsvanzelf\jsonapi\interfaces\HasAttributesInterface; +use alsvanzelf\jsonapi\interfaces\HasExtensionMembersInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; use alsvanzelf\jsonapi\objects\ResourceIdentifierObject; +use alsvanzelf\jsonapi\objects\ResourceObject; ini_set('display_errors', 1); error_reporting(-1); @@ -55,7 +58,7 @@ class ExampleDataset { public static function getRecord($type, $id) { if (!isset(self::$records[$type][$id])) { - throw new Exception('sorry, we have a limited dataset'); + throw new \Exception('sorry, we have a limited dataset'); } return self::$records[$type][$id]; @@ -121,6 +124,10 @@ public function getNamespace() { */ public function setVersion(ResourceInterface $resource, $version) { + if ($resource instanceof HasExtensionMembersInterface === false) { + throw new \Exception('resource doesn\'t have extension members'); + } + if ($resource instanceof ResourceDocument) { $resource->getResource()->addExtensionMember($this, 'id', $version); } @@ -143,9 +150,12 @@ public function getOfficialLink() { * optionally helpers for the specific profile */ + /** + * @param ResourceInterface&HasAttributesInterface $resource + */ public function setTimestamps(ResourceInterface $resource, ?\DateTimeInterface $created=null, ?\DateTimeInterface $updated=null) { - if ($resource instanceof ResourceIdentifierObject) { - throw new Exception('cannot add attributes to identifier objects'); + if ($resource instanceof HasAttributesInterface === false) { + throw new \Exception('cannot add attributes to identifier objects'); } $timestamps = []; @@ -156,6 +166,6 @@ public function setTimestamps(ResourceInterface $resource, ?\DateTimeInterface $ $timestamps['updated'] = $updated->format(\DateTime::ISO8601); } - $resource->add('timestamps', $timestamps); + $resource->addAttribute('timestamps', $timestamps); } } diff --git a/examples/errors_exception_native.php b/examples/errors_exception_native.php index b187b59..59fde02 100644 --- a/examples/errors_exception_native.php +++ b/examples/errors_exception_native.php @@ -13,7 +13,7 @@ */ try { - throw new Exception('unknown user', 404); + throw new \Exception('unknown user', 404); } catch (Exception $e) { $options = [ diff --git a/examples/relationships.php b/examples/relationships.php index 483ab1b..bc25dfe 100644 --- a/examples/relationships.php +++ b/examples/relationships.php @@ -78,7 +78,7 @@ $custom_relation = [ 'data' => ['cus' => 'tom'], ]; -$jsonapi->add_relation('custom', $custom_relation); +$jsonapi->addRelationship('custom', $custom_relation); /** * sending the response diff --git a/phpstan.bonus.neon b/phpstan.bonus.neon index 7a702e5..ae9db4e 100644 --- a/phpstan.bonus.neon +++ b/phpstan.bonus.neon @@ -3,7 +3,7 @@ includes: - vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: - level: 9 + level: 10 treatPhpDocTypesAsCertain: true diff --git a/phpstan.neon b/phpstan.neon index d1b333d..496ebc7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,6 @@ parameters: # slowly increase - level: 1 + level: 4 paths: - src/ - tests/ @@ -14,9 +14,11 @@ parameters: - src/resource.php - src/response.php + treatPhpDocTypesAsCertain: false + strictRules: allRules: false - + reportUnmatchedIgnoredErrors: true ignoreErrors: # add cases to ignore because they are too much work for now diff --git a/script/fix b/script/fix index 3d07227..c98b17e 100755 --- a/script/fix +++ b/script/fix @@ -81,7 +81,6 @@ if test "$HAS_TYPE" = 1; then $CONSOLE_PREFIX ./vendor/bin/phpcbf $EXTRA_ARGUMENTS $FILE_FILTER elif test "$TYPE" = "rector"; then - echo "${T_WARNING}Rector might not produce correct results until phpstan is on level 4 on the main branch${T_RESET}" $CONSOLE_PREFIX ./vendor/bin/rector process $EXTRA_ARGUMENTS $FILE_FILTER else @@ -93,7 +92,6 @@ else echo -e "${T_BOLD}Running fixes on the changed files (not only git-diff) between the base and the head branch${T_RESET}\n" echo "${T_INFO}Fixing refactors (rector)${T_RESET}" - echo "${T_WARNING}Rector might not produce correct results until phpstan is on level 4 on the main branch${T_RESET}" $CONSOLE_PREFIX ./vendor/bin/rector process $FILE_FILTER || true echo "${T_INFO}Fixing coding standards (phpcs)${T_RESET}" diff --git a/script/lint b/script/lint index d6fe577..41580fc 100755 --- a/script/lint +++ b/script/lint @@ -120,7 +120,6 @@ if test "$HAS_TYPE" = 1; then fi elif test "$TYPE" = "rector"; then - echo "${T_WARNING}Rector might not produce correct results until phpstan is on level 4 on the main branch${T_RESET}" $CONSOLE_PREFIX ./vendor/bin/rector process --dry-run $EXTRA_ARGUMENTS $FILE_FILTER else @@ -161,7 +160,6 @@ else echo -e '\n' echo "${T_INFO}Checking refactors (rector)${T_RESET}" - echo "${T_WARNING}Rector might not produce correct results until phpstan is on level 4 on the main branch${T_RESET}" $CONSOLE_PREFIX ./vendor/bin/rector process --memory-limit=4g --dry-run $FILE_FILTER 2> /dev/null \ && echo "${T_SUCCESS}Success${T_RESET}" diff --git a/src/CollectionDocument.php b/src/CollectionDocument.php index ed139c2..ba7c458 100644 --- a/src/CollectionDocument.php +++ b/src/CollectionDocument.php @@ -9,8 +9,8 @@ use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface; use alsvanzelf\jsonapi\interfaces\ResourceContainerInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; -use alsvanzelf\jsonapi\objects\ResourceObject; use alsvanzelf\jsonapi\objects\ResourceIdentifierObject; +use alsvanzelf\jsonapi\objects\ResourceObject; /** * this document is a set of Resources @@ -63,9 +63,6 @@ public function add($type, $id, array $attributes=[]) { } } - /** - * @inheritDoc - */ public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHref=null, $lastHref=null) { if ($previousHref !== null) { $this->addLink('prev', $previousHref); @@ -115,9 +112,6 @@ public function addResource(ResourceInterface $resource, array $options=[]) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); @@ -133,9 +127,6 @@ public function toArray() { * ResourceContainerInterface */ - /** - * @inheritDoc - */ public function getContainedResources() { return $this->resources; } diff --git a/src/DataDocument.php b/src/DataDocument.php index ed97d7f..a1667c1 100644 --- a/src/DataDocument.php +++ b/src/DataDocument.php @@ -58,9 +58,6 @@ public function addIncludedResourceObject(ResourceObject ...$resourceObjects) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); diff --git a/src/Document.php b/src/Document.php index 7fafe17..be79032 100644 --- a/src/Document.php +++ b/src/Document.php @@ -13,6 +13,9 @@ use alsvanzelf\jsonapi\helpers\Validator; use alsvanzelf\jsonapi\interfaces\DocumentInterface; use alsvanzelf\jsonapi\interfaces\ExtensionInterface; +use alsvanzelf\jsonapi\interfaces\HasExtensionMembersInterface; +use alsvanzelf\jsonapi\interfaces\HasLinksInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; use alsvanzelf\jsonapi\objects\JsonapiObject; use alsvanzelf\jsonapi\objects\LinkObject; @@ -22,7 +25,7 @@ /** * @see ResourceDocument, CollectionDocument, ErrorsDocument or MetaDocument */ -abstract class Document implements DocumentInterface, \JsonSerializable { +abstract class Document implements DocumentInterface, \JsonSerializable, HasLinksInterface, HasMetaInterface, HasExtensionMembersInterface { use AtMemberManager, ExtensionMemberManager, HttpStatusCodeManager, LinksManager { LinksManager::addLink as linkManagerAddLink; } @@ -41,7 +44,7 @@ abstract class Document implements DocumentInterface, \JsonSerializable { /** @var MetaObject */ protected $meta; - /** @var JsonapiObject */ + /** @var ?JsonapiObject */ protected $jsonapi; /** @var ExtensionInterface[] */ protected $extensions = []; @@ -259,9 +262,6 @@ public function applyProfile(ProfileInterface $profile) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = []; @@ -285,9 +285,6 @@ public function toArray() { return $array; } - /** - * @inheritDoc - */ public function toJson(array $options=[]) { $options = array_merge(self::$defaults, $options); @@ -309,9 +306,6 @@ public function toJson(array $options=[]) { return $json; } - /** - * @inheritDoc - */ public function sendResponse(array $options=[]) { $options = array_merge(self::$defaults, $options); diff --git a/src/ErrorsDocument.php b/src/ErrorsDocument.php index 12f2ade..4a8b4d1 100644 --- a/src/ErrorsDocument.php +++ b/src/ErrorsDocument.php @@ -125,9 +125,6 @@ public function addErrorObject(ErrorObject $errorObject) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); diff --git a/src/MetaDocument.php b/src/MetaDocument.php index 3f6e7dc..299ad20 100644 --- a/src/MetaDocument.php +++ b/src/MetaDocument.php @@ -55,9 +55,6 @@ public function add($key, $value, $level=Document::LEVEL_ROOT) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); diff --git a/src/ResourceDocument.php b/src/ResourceDocument.php index 8db9d09..ff7ebca 100644 --- a/src/ResourceDocument.php +++ b/src/ResourceDocument.php @@ -8,6 +8,7 @@ use alsvanzelf\jsonapi\exceptions\Exception; use alsvanzelf\jsonapi\exceptions\InputException; use alsvanzelf\jsonapi\helpers\Converter; +use alsvanzelf\jsonapi\interfaces\HasAttributesInterface; use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; use alsvanzelf\jsonapi\objects\AttributesObject; @@ -21,7 +22,7 @@ * it can contain other Resources as relationships * a CollectionDocument should be used if the primary Resource is (or can be) a set */ -class ResourceDocument extends DataDocument implements ResourceInterface { +class ResourceDocument extends DataDocument implements HasAttributesInterface, ResourceInterface { /** @var ResourceIdentifierObject|ResourceObject */ protected $resource; /** @var array */ @@ -85,7 +86,9 @@ public static function fromObject($attributes, $type=null, $id=null, array $opti * @param array $options optional {@see ResourceDocument::$defaults} */ public function add($key, $value, array $options=[]) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } $this->resource->add($key, $value, $options); } @@ -102,7 +105,9 @@ public function add($key, $value, array $options=[]) { * @param array $options optional {@see ResourceDocument::$defaults} */ public function addRelationship($key, $relation, array $links=[], array $meta=[], array $options=[]) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } $options = array_merge(self::$defaults, $options); @@ -120,7 +125,9 @@ public function addRelationship($key, $relation, array $links=[], array $meta=[] * @param string $level one of the Document::LEVEL_* constants, optional, defaults to Document::LEVEL_ROOT */ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } if ($level === Document::LEVEL_RESOURCE) { $this->resource->addLink($key, $href, $meta); @@ -137,7 +144,9 @@ public function addLink($key, $href, array $meta=[], $level=Document::LEVEL_ROOT * @param array $meta optional */ public function setSelfLink($href, array $meta=[], $level=Document::LEVEL_RESOURCE) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } if ($level === Document::LEVEL_RESOURCE) { $this->resource->setSelfLink($href, $meta); @@ -191,7 +200,9 @@ public function setLocalId($localId) { * @param array $options optional {@see ResourceObject::$defaults} */ public function setAttributesObject(AttributesObject $attributesObject, array $options=[]) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } $this->resource->setAttributesObject($attributesObject, $options); } @@ -206,7 +217,9 @@ public function setAttributesObject(AttributesObject $attributesObject, array $o * @param array $options optional {@see ResourceDocument::$defaults} */ public function addRelationshipObject($key, RelationshipObject $relationshipObject, array $options=[]) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } $options = array_merge(self::$defaults, $options); @@ -226,7 +239,9 @@ public function addRelationshipObject($key, RelationshipObject $relationshipObje * @param array $options optional {@see ResourceDocument::$defaults} */ public function setRelationshipsObject(RelationshipsObject $relationshipsObject, array $options=[]) { - $this->ensureResourceObject(); + if ($this->resource instanceof ResourceObject === false) { + throw new Exception('the resource is an identifier-only object'); + } $options = array_merge(self::$defaults, $options); @@ -256,6 +271,8 @@ public function setPrimaryResource(ResourceInterface $resource, array $options=[ throw new InputException('does not make sense to set a document inside a document, use ResourceObject or ResourceIdentifierObject instead'); } + /** @var ResourceIdentifierObject|ResourceObject $resource */ + $options = array_merge(self::$defaults, $options); $this->resource = $resource; @@ -269,24 +286,10 @@ public function setPrimaryResource(ResourceInterface $resource, array $options=[ * internal api */ - /** - * @internal - * - * @throws Exception - */ - private function ensureResourceObject() { - if ($this->resource instanceof ResourceObject === false) { - throw new Exception('the resource is an identifier-only object'); - } - } - /** * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); @@ -299,12 +302,17 @@ public function toArray() { } /** - * ResourceInterface + * HasAttributesInterface */ + public function addAttribute($key, $value, array $options=[]) { + return $this->add($key, $value); + } + /** - * @inheritDoc + * ResourceInterface */ + public function getResource($identifierOnly=false) { return $this->resource->getResource($identifierOnly); } diff --git a/src/extensions/AtomicOperationsDocument.php b/src/extensions/AtomicOperationsDocument.php index 1599fd8..fc16caf 100644 --- a/src/extensions/AtomicOperationsDocument.php +++ b/src/extensions/AtomicOperationsDocument.php @@ -39,9 +39,6 @@ public function addResults(ResourceInterface ...$resources) { * DocumentInterface */ - /** - * @inheritDoc - */ public function toArray() { $results = []; foreach ($this->results as $result) { diff --git a/src/extensions/AtomicOperationsExtension.php b/src/extensions/AtomicOperationsExtension.php index b94cfe6..6b6cffd 100644 --- a/src/extensions/AtomicOperationsExtension.php +++ b/src/extensions/AtomicOperationsExtension.php @@ -16,16 +16,10 @@ class AtomicOperationsExtension implements ExtensionInterface { * ExtensionInterface */ - /** - * @inheritDoc - */ public function getOfficialLink() { return 'https://jsonapi.org/ext/atomic/'; } - /** - * @inheritDoc - */ public function getNamespace() { return 'atomic'; } diff --git a/src/helpers/RequestParser.php b/src/helpers/RequestParser.php index 14a8373..d65b180 100644 --- a/src/helpers/RequestParser.php +++ b/src/helpers/RequestParser.php @@ -190,10 +190,10 @@ public function hasSortFields() { * @todo return some kind of SortFieldObject * * @param array $options optional {@see RequestParser::$defaults} - * @return string[]|array[] { - * @var string $field the sort field, without any minus sign for descending sort order - * @var string $order one of the RequestParser::SORT_* constants - * } + * @return string[]|array */ public function getSortFields(array $options=[]) { if ($this->queryParameters['sort'] === '') { diff --git a/src/helpers/Validator.php b/src/helpers/Validator.php index 692d473..2c9e573 100644 --- a/src/helpers/Validator.php +++ b/src/helpers/Validator.php @@ -35,7 +35,7 @@ class Validator { * * @see https://jsonapi.org/format/1.1/#document-resource-object-fields * - * @param string[] $fieldName + * @param string[] $fieldNames * @param string $objectContainer one of the Validator::OBJECT_CONTAINER_* constants * @param array $options optional {@see Validator::$defaults} * @@ -65,7 +65,7 @@ public function claimUsedFields(array $fieldNames, $objectContainer, array $opti } /** - * @param string $objectContainer one of the Validator::OBJECT_CONTAINER_* constants + * @param string $objectContainerToClear one of the Validator::OBJECT_CONTAINER_* constants */ public function clearUsedFields($objectContainerToClear) { foreach ($this->usedFields as $fieldName => $containerFound) { diff --git a/src/interfaces/HasAttributesInterface.php b/src/interfaces/HasAttributesInterface.php new file mode 100644 index 0000000..889190d --- /dev/null +++ b/src/interfaces/HasAttributesInterface.php @@ -0,0 +1,17 @@ +addLink()} + * + * @param string $key + * @param string $href + */ + public function appendLink($key, $href, array $meta=[]); + + /** + * set a key containing a LinkObject + * + * @param string $key + */ + public function addLinkObject($key, LinkObject $linkObject); + + /** + * set a key containing a LinksArray + * + * @deprecated array links are not supported anymore {@see ->addLinkObject()} + * + * @param string $key + */ + public function addLinksArray($key, LinksArray $linksArray); + + /** + * append a LinkObject to a key with a LinksArray + * + * @deprecated array links are not supported anymore {@see ->addLinkObject()} + * + * @param string $key + */ + public function appendLinkObject($key, LinkObject $linkObject); + + /** + * set a LinksObject containing all links + */ + public function setLinksObject(LinksObject $linksObject); +} diff --git a/src/interfaces/HasMetaInterface.php b/src/interfaces/HasMetaInterface.php new file mode 100644 index 0000000..52ac6b4 --- /dev/null +++ b/src/interfaces/HasMetaInterface.php @@ -0,0 +1,13 @@ +attributes !== []) { return false; @@ -99,9 +92,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/ErrorObject.php b/src/objects/ErrorObject.php index 80120f1..29e9ae7 100644 --- a/src/objects/ErrorObject.php +++ b/src/objects/ErrorObject.php @@ -4,16 +4,16 @@ use alsvanzelf\jsonapi\Document; use alsvanzelf\jsonapi\exceptions\InputException; -use alsvanzelf\jsonapi\helpers\AtMemberManager; use alsvanzelf\jsonapi\helpers\Converter; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\helpers\HttpStatusCodeManager; use alsvanzelf\jsonapi\helpers\LinksManager; use alsvanzelf\jsonapi\helpers\Validator; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\interfaces\HasLinksInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; -class ErrorObject implements ObjectInterface { - use AtMemberManager, ExtensionMemberManager, HttpStatusCodeManager, LinksManager; +class ErrorObject extends AbstractObject implements HasLinksInterface, HasMetaInterface { + use HttpStatusCodeManager, LinksManager; /** @var string */ protected $id; @@ -279,9 +279,6 @@ public function setMetaObject(MetaObject $metaObject) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->id !== null) { return false; @@ -317,9 +314,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/JsonapiObject.php b/src/objects/JsonapiObject.php index 980b0b2..3d581d9 100644 --- a/src/objects/JsonapiObject.php +++ b/src/objects/JsonapiObject.php @@ -3,27 +3,24 @@ namespace alsvanzelf\jsonapi\objects; use alsvanzelf\jsonapi\Document; -use alsvanzelf\jsonapi\helpers\AtMemberManager; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\interfaces\ExtensionInterface; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\MetaObject; -class JsonapiObject implements ObjectInterface { - use AtMemberManager, ExtensionMemberManager; - +class JsonapiObject extends AbstractObject implements HasMetaInterface { /** @var string */ protected $version; /** @var ExtensionInterface[] */ protected $extensions = []; - /** @var ProfileInterface */ + /** @var ProfileInterface[] */ protected $profiles = []; /** @var MetaObject */ protected $meta; /** - * @param string $version one of the Document::JSONAPI_VERSION_* constants, optional, defaults to Document::JSONAPI_VERSION_LATEST + * @param ?string $version one of the Document::JSONAPI_VERSION_* constants, optional, defaults to Document::JSONAPI_VERSION_LATEST */ public function __construct($version=Document::JSONAPI_VERSION_LATEST) { if ($version !== null) { @@ -83,9 +80,6 @@ public function setMetaObject(MetaObject $metaObject) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->version !== null) { return false; @@ -109,9 +103,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/LinkObject.php b/src/objects/LinkObject.php index 244d103..e7a06e0 100644 --- a/src/objects/LinkObject.php +++ b/src/objects/LinkObject.php @@ -2,14 +2,11 @@ namespace alsvanzelf\jsonapi\objects; -use alsvanzelf\jsonapi\helpers\AtMemberManager; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\MetaObject; -class LinkObject implements ObjectInterface { - use AtMemberManager, ExtensionMemberManager; - +class LinkObject extends AbstractObject implements HasMetaInterface { /** @var string */ protected $href; /** @var string */ @@ -101,7 +98,7 @@ public function setDescribedByLinkObject(LinkObject $describedBy) { } /** - * @param string $friendlyTitle + * @param string $humanTitle */ public function setHumanTitle($humanTitle) { $this->title = $humanTitle; @@ -134,9 +131,6 @@ public function setMetaObject(MetaObject $metaObject) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->href !== null) { return false; @@ -169,9 +163,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/LinksArray.php b/src/objects/LinksArray.php index d4ae042..a0f27b1 100644 --- a/src/objects/LinksArray.php +++ b/src/objects/LinksArray.php @@ -9,6 +9,8 @@ /** * an array of links (strings and LinkObjects), used for: * - type links in an ErrorObject + * + * @deprecated array links are not supported anymore */ class LinksArray implements ObjectInterface { /** @var array with string|LinkObject */ @@ -77,16 +79,10 @@ public function addLinkObject(LinkObject $linkObject) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { return ($this->links === []); } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/LinksObject.php b/src/objects/LinksObject.php index 1e759ee..2422d54 100644 --- a/src/objects/LinksObject.php +++ b/src/objects/LinksObject.php @@ -3,17 +3,13 @@ namespace alsvanzelf\jsonapi\objects; use alsvanzelf\jsonapi\exceptions\DuplicateException; -use alsvanzelf\jsonapi\helpers\AtMemberManager; use alsvanzelf\jsonapi\helpers\Converter; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\helpers\Validator; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\LinkObject; use alsvanzelf\jsonapi\objects\LinksArray; -class LinksObject implements ObjectInterface { - use AtMemberManager, ExtensionMemberManager; - +class LinksObject extends AbstractObject { /** @var array with string|LinkObject */ protected $links = []; @@ -164,9 +160,6 @@ public function appendLinkObject($key, LinkObject $linkObject) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->links !== []) { return false; @@ -181,9 +174,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; @@ -198,8 +188,8 @@ public function toArray() { if ($link instanceof LinkObject && $link->isEmpty() === false) { $array[$key] = $link->toArray(); } - elseif ($link instanceof LinksArray && $link->isEmpty() === false) { - $array[$key] = $link->toArray(); + elseif ($link instanceof LinksArray && $link->isEmpty() === false) { // @phpstan-ignore method.deprecatedClass + $array[$key] = $link->toArray(); // @phpstan-ignore method.deprecatedClass } elseif ($link instanceof LinkObject && $link->isEmpty()) { $array[$key] = null; diff --git a/src/objects/MetaObject.php b/src/objects/MetaObject.php index 03e9e1e..e98a2c9 100644 --- a/src/objects/MetaObject.php +++ b/src/objects/MetaObject.php @@ -2,15 +2,11 @@ namespace alsvanzelf\jsonapi\objects; -use alsvanzelf\jsonapi\helpers\AtMemberManager; use alsvanzelf\jsonapi\helpers\Converter; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\helpers\Validator; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; -class MetaObject implements ObjectInterface { - use AtMemberManager, ExtensionMemberManager; - +class MetaObject extends AbstractObject { /** @var array */ protected $meta = []; @@ -64,9 +60,6 @@ public function add($key, $value) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->meta !== []) { return false; @@ -81,9 +74,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; diff --git a/src/objects/RelationshipObject.php b/src/objects/RelationshipObject.php index 7644cd5..6cb0efd 100644 --- a/src/objects/RelationshipObject.php +++ b/src/objects/RelationshipObject.php @@ -4,19 +4,19 @@ use alsvanzelf\jsonapi\CollectionDocument; use alsvanzelf\jsonapi\exceptions\InputException; -use alsvanzelf\jsonapi\helpers\AtMemberManager; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\helpers\LinksManager; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\interfaces\HasLinksInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; use alsvanzelf\jsonapi\interfaces\PaginableInterface; use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\LinksObject; use alsvanzelf\jsonapi\objects\MetaObject; use alsvanzelf\jsonapi\objects\ResourceObject; -class RelationshipObject implements ObjectInterface, PaginableInterface, RecursiveResourceContainerInterface { - use AtMemberManager, ExtensionMemberManager, LinksManager; +class RelationshipObject extends AbstractObject implements PaginableInterface, RecursiveResourceContainerInterface, HasLinksInterface, HasMetaInterface { + use LinksManager; const TO_ONE = 'one'; const TO_MANY = 'many'; @@ -145,8 +145,6 @@ public function setRelatedLink($href, array $meta=[]) { } /** - * @inheritDoc - * * @throws InputException if used on a to-one relationship */ public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHref=null, $lastHref=null) { @@ -255,9 +253,6 @@ public function hasResource(ResourceInterface $otherResource) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->type === RelationshipObject::TO_ONE && $this->resource !== null) { return false; @@ -281,9 +276,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; @@ -320,9 +312,6 @@ public function toArray() { * RecursiveResourceContainerInterface */ - /** - * @inheritDoc - */ public function getNestedContainedResourceObjects() { if ($this->isEmpty()) { return []; diff --git a/src/objects/RelationshipsObject.php b/src/objects/RelationshipsObject.php index c0bf3e0..8c8d0be 100644 --- a/src/objects/RelationshipsObject.php +++ b/src/objects/RelationshipsObject.php @@ -3,18 +3,14 @@ namespace alsvanzelf\jsonapi\objects; use alsvanzelf\jsonapi\exceptions\DuplicateException; -use alsvanzelf\jsonapi\helpers\AtMemberManager; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; use alsvanzelf\jsonapi\helpers\Validator; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\LinkObject; use alsvanzelf\jsonapi\objects\RelationshipObject; use alsvanzelf\jsonapi\objects\ResourceObject; -class RelationshipsObject implements ObjectInterface, RecursiveResourceContainerInterface { - use AtMemberManager, ExtensionMemberManager; - +class RelationshipsObject extends AbstractObject implements RecursiveResourceContainerInterface { /** @var RelationshipObject[] */ protected $relationships = []; @@ -74,9 +70,6 @@ public function getKeys() { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->relationships !== []) { return false; @@ -91,9 +84,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; @@ -115,9 +105,6 @@ public function toArray() { * RecursiveResourceContainerInterface */ - /** - * @inheritDoc - */ public function getNestedContainedResourceObjects() { $resourceObjects = []; diff --git a/src/objects/ResourceIdentifierObject.php b/src/objects/ResourceIdentifierObject.php index 05aaa6b..715456d 100644 --- a/src/objects/ResourceIdentifierObject.php +++ b/src/objects/ResourceIdentifierObject.php @@ -2,18 +2,15 @@ namespace alsvanzelf\jsonapi\objects; -use alsvanzelf\jsonapi\exceptions\Exception; use alsvanzelf\jsonapi\exceptions\DuplicateException; -use alsvanzelf\jsonapi\helpers\AtMemberManager; -use alsvanzelf\jsonapi\helpers\ExtensionMemberManager; +use alsvanzelf\jsonapi\exceptions\Exception; use alsvanzelf\jsonapi\helpers\Validator; -use alsvanzelf\jsonapi\interfaces\ObjectInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; +use alsvanzelf\jsonapi\objects\AbstractObject; use alsvanzelf\jsonapi\objects\MetaObject; -class ResourceIdentifierObject implements ObjectInterface, ResourceInterface { - use AtMemberManager, ExtensionMemberManager; - +class ResourceIdentifierObject extends AbstractObject implements HasMetaInterface, ResourceInterface { /** @var string */ protected $type; /** @var string */ @@ -179,9 +176,6 @@ public function getIdentificationKey() { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if ($this->type !== null || $this->primaryId() !== null) { return false; @@ -199,9 +193,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = []; @@ -232,9 +223,6 @@ public function toArray() { * ResourceInterface */ - /** - * @inheritDoc - */ public function getResource($identifierOnly=false) { return $this; } diff --git a/src/objects/ResourceObject.php b/src/objects/ResourceObject.php index a86006d..e0d59d3 100644 --- a/src/objects/ResourceObject.php +++ b/src/objects/ResourceObject.php @@ -7,6 +7,8 @@ use alsvanzelf\jsonapi\helpers\Converter; use alsvanzelf\jsonapi\helpers\LinksManager; use alsvanzelf\jsonapi\helpers\Validator; +use alsvanzelf\jsonapi\interfaces\HasAttributesInterface; +use alsvanzelf\jsonapi\interfaces\HasLinksInterface; use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; use alsvanzelf\jsonapi\objects\AttributesObject; @@ -14,7 +16,7 @@ use alsvanzelf\jsonapi\objects\RelationshipsObject; use alsvanzelf\jsonapi\objects\ResourceIdentifierObject; -class ResourceObject extends ResourceIdentifierObject implements RecursiveResourceContainerInterface { +class ResourceObject extends ResourceIdentifierObject implements HasAttributesInterface, HasLinksInterface, RecursiveResourceContainerInterface { use LinksManager; /** @var AttributesObject */ @@ -193,12 +195,17 @@ public function hasIdentifierPropertiesOnly() { } /** - * ResourceInterface + * HasAttributesInterface */ + public function addAttribute($key, $value, array $options=[]) { + return $this->add($key, $value); + } + /** - * @inheritDoc + * ResourceInterface */ + public function getResource($identifierOnly=false) { if ($identifierOnly) { return ResourceIdentifierObject::fromResourceObject($this); @@ -211,9 +218,6 @@ public function getResource($identifierOnly=false) { * ObjectInterface */ - /** - * @inheritDoc - */ public function isEmpty() { if (parent::isEmpty() === false) { return false; @@ -231,9 +235,6 @@ public function isEmpty() { return true; } - /** - * @inheritDoc - */ public function toArray() { $array = parent::toArray(); @@ -254,9 +255,6 @@ public function toArray() { * RecursiveResourceContainerInterface */ - /** - * @inheritDoc - */ public function getNestedContainedResourceObjects() { if ($this->relationships === null) { return []; diff --git a/src/profiles/CursorPaginationProfile.php b/src/profiles/CursorPaginationProfile.php index e95f523..bed7ad4 100644 --- a/src/profiles/CursorPaginationProfile.php +++ b/src/profiles/CursorPaginationProfile.php @@ -4,6 +4,9 @@ use alsvanzelf\jsonapi\Document; use alsvanzelf\jsonapi\ResourceDocument; +use alsvanzelf\jsonapi\exceptions\InputException; +use alsvanzelf\jsonapi\interfaces\HasLinksInterface; +use alsvanzelf\jsonapi\interfaces\HasMetaInterface; use alsvanzelf\jsonapi\interfaces\PaginableInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; @@ -138,11 +141,15 @@ public function generateNextLink($baseOrCurrentUrl, $afterCursor) { * * @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-links * - * @param PaginableInterface $paginable - * @param LinkObject $previousLinkObject - * @param LinkObject $nextLinkObject + * @param PaginableInterface&HasLinksInterface $paginable + * @param LinkObject $previousLinkObject + * @param LinkObject $nextLinkObject */ public function setPaginationLinkObjects(PaginableInterface $paginable, LinkObject $previousLinkObject, LinkObject $nextLinkObject) { + if ($paginable instanceof HasLinksInterface === false) { + throw new InputException('unsupported paginable to set pagination links on'); + } + $paginable->addLinkObject('prev', $previousLinkObject); $paginable->addLinkObject('next', $nextLinkObject); } @@ -182,10 +189,14 @@ public function setPaginationLinkObjectsExplicitlyEmpty(PaginableInterface $pagi * * @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-item-metadata * - * @param ResourceInterface $resource - * @param string $cursor + * @param ResourceInterface&HasMetaInterface $resource + * @param string $cursor */ public function setItemMeta(ResourceInterface $resource, $cursor) { + if ($resource instanceof HasMetaInterface === false) { + throw new InputException('resource doesn\'t support meta'); + } + $metadata = [ 'cursor' => $cursor, ]; @@ -208,12 +219,16 @@ public function setItemMeta(ResourceInterface $resource, $cursor) { * * @see https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#terms-pagination-metadata * - * @param PaginableInterface $paginable - * @param int $exactTotal optional - * @param int $bestGuessTotal optional - * @param boolean $rangeIsTruncated optional, if both after and before are supplied but the items exceed requested or max size + * @param PaginableInterface&HasMetaInterface $paginable + * @param int $exactTotal optional + * @param int $bestGuessTotal optional + * @param boolean $rangeIsTruncated optional, if both after and before are supplied but the items exceed requested or max size */ public function setPaginationMeta(PaginableInterface $paginable, $exactTotal=null, $bestGuessTotal=null, $rangeIsTruncated=null) { + if ($paginable instanceof HasMetaInterface === false) { + throw new InputException('paginable doesn\'t support meta'); + } + $metadata = []; if ($exactTotal !== null) { @@ -385,9 +400,6 @@ private function setQueryParameter($url, $key, $value) { * ProfileInterface */ - /** - * @inheritDoc - */ public function getOfficialLink() { return 'https://jsonapi.org/profiles/ethanresnick/cursor-pagination/'; } diff --git a/tests/ConverterTest.php b/tests/ConverterTest.php index 0f4f35e..d2d5112 100644 --- a/tests/ConverterTest.php +++ b/tests/ConverterTest.php @@ -127,6 +127,6 @@ public function testMergeProfilesInContentType_HappyPath() { class TestObject { public $foo = 'bar'; public $baz = 42; - private $secret = 'value'; + private $secret = 'value'; // @phpstan-ignore property.onlyWritten public function method() {} } diff --git a/tests/DocumentTest.php b/tests/DocumentTest.php index 8a26204..6e8e51c 100644 --- a/tests/DocumentTest.php +++ b/tests/DocumentTest.php @@ -41,12 +41,7 @@ public function testAddLink_HappyPath() { $this->assertArrayHasKey('links', $array); $this->assertCount(1, $array['links']); $this->assertArrayHasKey('foo', $array['links']); - if (method_exists($this, 'assertIsString')) { - $this->assertIsString($array['links']['foo']); - } - else { - $this->assertIsString($array['links']['foo']); - } + $this->assertIsString($array['links']['foo']); $this->assertSame('https://jsonapi.org', $array['links']['foo']); } @@ -57,12 +52,7 @@ public function testAddLink_WithMeta() { $array = $document->toArray(); $this->assertCount(1, $array['links']); - if (method_exists($this, 'assertIsArray')) { - $this->assertIsArray($array['links']['foo']); - } - else { - $this->assertIsArray($array['links']['foo']); - } + $this->assertIsArray($array['links']['foo']); $this->assertCount(2, $array['links']['foo']); $this->assertArrayHasKey('href', $array['links']['foo']); $this->assertArrayHasKey('meta', $array['links']['foo']); @@ -121,12 +111,7 @@ public function testSetDescribedByLink_HappyPath() { $array = $document->toArray(); $this->assertCount(1, $array['links']); - if (method_exists($this, 'assertIsArray')) { - $this->assertIsArray($array['links']['describedby']); - } - else { - $this->assertIsArray($array['links']['describedby']); - } + $this->assertIsArray($array['links']['describedby']); $this->assertCount(2, $array['links']['describedby']); $this->assertArrayHasKey('href', $array['links']['describedby']); $this->assertArrayHasKey('meta', $array['links']['describedby']); @@ -164,12 +149,7 @@ public function testAddMeta_HappyPath() { $this->assertArrayHasKey('meta', $array); $this->assertCount(1, $array['meta']); $this->assertArrayHasKey('foo', $array['meta']); - if (method_exists($this, 'assertIsString')) { - $this->assertIsString($array['meta']['foo']); - } - else { - $this->assertIsString($array['meta']['foo']); - } + $this->assertIsString($array['meta']['foo']); $this->assertSame('bar', $array['meta']['foo']); } @@ -188,12 +168,7 @@ public function testAddMeta_AtJsonapiLevel() { $this->assertArrayHasKey('meta', $array['jsonapi']); $this->assertCount(1, $array['jsonapi']['meta']); $this->assertArrayHasKey('foo', $array['jsonapi']['meta']); - if (method_exists($this, 'assertIsString')) { - $this->assertIsString($array['jsonapi']['meta']['foo']); - } - else { - $this->assertIsString($array['jsonapi']['meta']['foo']); - } + $this->assertIsString($array['jsonapi']['meta']['foo']); $this->assertSame('bar', $array['jsonapi']['meta']['foo']); } diff --git a/tests/ErrorsDocumentTest.php b/tests/ErrorsDocumentTest.php index d3add16..d7be29b 100644 --- a/tests/ErrorsDocumentTest.php +++ b/tests/ErrorsDocumentTest.php @@ -36,11 +36,6 @@ public function testFromException_HappyPath() { * @group non-php5 */ public function testFromException_AllowsThrowable() { - if (PHP_MAJOR_VERSION < 7) { - $this->markTestSkipped('can not run in php5'); - return; - } - $document = ErrorsDocument::fromException(new \Error('foo', 42)); $array = $document->toArray(); diff --git a/tests/ExampleOutputTest.php b/tests/ExampleOutputTest.php index 6c648a3..4ccd0c9 100644 --- a/tests/ExampleOutputTest.php +++ b/tests/ExampleOutputTest.php @@ -28,7 +28,6 @@ public function testOutput($generator, $expectedJson, array $options=[], $testNa if ($expectedJson === null && file_exists($actualJsonPath) === false) { file_put_contents($actualJsonPath, $actualJson); $this->markTestSkipped('no stored json to test against, try again'); - return; } $this->assertSame($expectedJson, $actualJson); diff --git a/tests/example_output/ExampleTimestampsProfile.php b/tests/example_output/ExampleTimestampsProfile.php index ad485bc..db6aaa8 100644 --- a/tests/example_output/ExampleTimestampsProfile.php +++ b/tests/example_output/ExampleTimestampsProfile.php @@ -2,18 +2,22 @@ namespace alsvanzelf\jsonapiTests\example_output; +use alsvanzelf\jsonapi\exceptions\InputException; +use alsvanzelf\jsonapi\interfaces\HasAttributesInterface; use alsvanzelf\jsonapi\interfaces\ProfileInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; -use alsvanzelf\jsonapi\objects\ResourceIdentifierObject; class ExampleTimestampsProfile implements ProfileInterface { public function getOfficialLink() { return 'https://jsonapi.org/recommendations/#authoring-profiles'; } + /** + * @param ResourceInterface&HasAttributesInterface $resource + */ public function setTimestamps(ResourceInterface $resource, ?\DateTimeInterface $created=null, ?\DateTimeInterface $updated=null) { - if ($resource instanceof ResourceIdentifierObject) { - throw new \Exception('cannot add attributes to identifier objects'); + if ($resource instanceof HasAttributesInterface === false) { + throw new InputException('cannot add attributes to identifier objects'); } $timestamps = []; @@ -24,6 +28,6 @@ public function setTimestamps(ResourceInterface $resource, ?\DateTimeInterface $ $timestamps['updated'] = $updated->format(\DateTime::ISO8601); } - $resource->add('timestamps', $timestamps); + $resource->addAttribute('timestamps', $timestamps); } } diff --git a/tests/example_output/ExampleVersionExtension.php b/tests/example_output/ExampleVersionExtension.php index bde454a..fc80ffb 100644 --- a/tests/example_output/ExampleVersionExtension.php +++ b/tests/example_output/ExampleVersionExtension.php @@ -3,7 +3,9 @@ namespace alsvanzelf\jsonapiTests\example_output; use alsvanzelf\jsonapi\ResourceDocument; +use alsvanzelf\jsonapi\exceptions\InputException; use alsvanzelf\jsonapi\interfaces\ExtensionInterface; +use alsvanzelf\jsonapi\interfaces\HasExtensionMembersInterface; use alsvanzelf\jsonapi\interfaces\ResourceInterface; class ExampleVersionExtension implements ExtensionInterface { @@ -16,6 +18,10 @@ public function getNamespace() { } public function setVersion(ResourceInterface $resource, $version) { + if ($resource instanceof HasExtensionMembersInterface === false) { + throw new InputException('resource doesn\'t have extension members'); + } + if ($resource instanceof ResourceDocument) { $resource->getResource()->addExtensionMember($this, 'id', $version); } diff --git a/tests/helpers/TestableNonInterfaceServerRequestInterface.php b/tests/helpers/TestableNonInterfaceServerRequestInterface.php index 944861b..5794c86 100644 --- a/tests/helpers/TestableNonInterfaceServerRequestInterface.php +++ b/tests/helpers/TestableNonInterfaceServerRequestInterface.php @@ -39,7 +39,10 @@ public function withUploadedFiles(array $uploadedFiles) { return $this; } - public function getParsedBody() {} + public function getParsedBody() { + return null; + } + public function withParsedBody($data) { return $this; } diff --git a/tests/helpers/TestableNonInterfaceStreamInterface.php b/tests/helpers/TestableNonInterfaceStreamInterface.php index 1590964..fb36096 100644 --- a/tests/helpers/TestableNonInterfaceStreamInterface.php +++ b/tests/helpers/TestableNonInterfaceStreamInterface.php @@ -30,9 +30,13 @@ public function __toString() { public function close() {} - public function detach() {} + public function detach() { + return null; + } - public function getSize() {} + public function getSize() { + return null; + } public function tell() { return 0; diff --git a/tests/helpers/TestableNonInterfaceUriInterface.php b/tests/helpers/TestableNonInterfaceUriInterface.php index e6f6ad0..bdb9af8 100644 --- a/tests/helpers/TestableNonInterfaceUriInterface.php +++ b/tests/helpers/TestableNonInterfaceUriInterface.php @@ -43,7 +43,7 @@ public function getHost() { } public function getPort() { - return ''; + return null; } public function getPath() { diff --git a/tests/objects/ErrorObjectTest.php b/tests/objects/ErrorObjectTest.php index bf43f57..9463a1c 100644 --- a/tests/objects/ErrorObjectTest.php +++ b/tests/objects/ErrorObjectTest.php @@ -91,11 +91,6 @@ public function testFromException_NamespacedException() { * @group non-php5 */ public function testFromException_NamespacedThrowable() { - if (PHP_MAJOR_VERSION < 7) { - $this->markTestSkipped('can not run in php5'); - return; - } - $exception = new TestError(); $errorObject = ErrorObject::fromException($exception); diff --git a/tests/objects/RelationshipObjectTest.php b/tests/objects/RelationshipObjectTest.php index 9861ac6..a09dec1 100644 --- a/tests/objects/RelationshipObjectTest.php +++ b/tests/objects/RelationshipObjectTest.php @@ -298,12 +298,7 @@ public function testToArray_EmptyResources() { $array = $relationshipObject->toArray(); $this->assertArrayHasKey('data', $array); - if (method_exists($this, 'assertIsArray')) { - $this->assertIsArray($array['data']); - } - else { - $this->assertIsArray($array['data']); - } + $this->assertIsArray($array['data']); } public function testIsEmpty_WithAtMembers() {