Skip to content

Linkage #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 16 additions & 18 deletions src/Document/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function setIncluded(IdentifiableResource ...$included)
$this->included = $included;
}

public function setIsSparse()
public function markSparse()
{
$this->is_sparse = true;
}
Expand Down Expand Up @@ -108,36 +108,34 @@ private function enforceFullLinkage()
if ($this->is_sparse || empty($this->included)) {
return;
}
foreach ($this->included as $resource) {
if (!$this->hasLinkTo($resource)) {
throw new \LogicException("Full linkage is required for $resource");
foreach ($this->included as $included_resource) {
if (!$this->hasLinkTo($included_resource)) {
throw new \LogicException("Full linkage is required for $included_resource");
}
}
}

private function hasLinkTo(IdentifiableResource $resource): bool
{
foreach ($this->toDataItems() as $my_resource) {
if ($my_resource instanceof ResourceObject) {
if ($my_resource->hasRelationTo($resource)) {
return true;
}
/** @var ResourceObject $my_resource */
foreach ($this->toResourceObjects() as $my_resource) {
if ($my_resource->hasRelationTo($resource)) {
return true;
}
}
return false;
}

/**
* @return IdentifiableResource[]
*/
private function toDataItems(): array
private function toResourceObjects(): \Generator
{
if ($this->data instanceof IdentifiableResource) {
return [$this->data];
if ($this->data instanceof ResourceObject) {
yield $this->data;
} elseif (is_array($this->data)) {
return $this->data;
} else {
return [];
foreach ($this->data as $datum) {
if ($datum instanceof ResourceObject) {
yield $datum;
}
}
}
}
}
3 changes: 3 additions & 0 deletions src/Document/Resource/Relationship/Linkage.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public static function fromManyResourceIds(ResourceId ...$data): self
public function isLinkedTo(IdentifiableResource $resource): bool
{
if ($this->data) {
if ($this->data instanceof ResourceId) {
return $this->data->isEqualTo($resource);
}
foreach ($this->data as $my_resource) {
if ($resource->isEqualTo($my_resource)) {
return true;
Expand Down
2 changes: 1 addition & 1 deletion test/Document/CompoundDocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public function testFullLinkageIsRequired()
public function testFullLinkageIsNotRequiredIfSparse()
{
$doc = Document::fromResource(new NullData);
$doc->setIsSparse();
$doc->markSparse();
$doc->setIncluded(
new ResourceObject('apples', '1')
);
Expand Down
48 changes: 44 additions & 4 deletions test/Document/Resource/Relationship/LinkageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,34 @@

namespace JsonApiPhp\JsonApi\Test\Document\Resource\Relationship;

use JsonApiPhp\JsonApi\Document\Resource\NullData;
use JsonApiPhp\JsonApi\Document\Resource\Relationship\Linkage;
use JsonApiPhp\JsonApi\Document\Resource\ResourceId;
use JsonApiPhp\JsonApi\Test\HasAssertEqualsAsJson;
use phpDocumentor\Reflection\DocBlock\Tags\Link;
use PHPUnit\Framework\TestCase;

class LinkageTest extends TestCase
{
use HasAssertEqualsAsJson;

public function testNullLinkage()
public function testCanCreateNullLinkage()
{
$this->assertEqualsAsJson(
null,
Linkage::nullLinkage()
);
}

public function testEmptyArrayLinkage()
public function testCanCreateEmptyArrayLinkage()
{
$this->assertEqualsAsJson(
[],
Linkage::emptyArrayLinkage()
);
}

public function testFromResourceId()
public function testCanCreateFromResourceId()
{
$this->assertEqualsAsJson(
[
Expand All @@ -50,7 +52,7 @@ public function testFromResourceId()
);
}

public function testFromResourceIds()
public function testCanCreateFromResourceIds()
{
$this->assertEqualsAsJson(
[
Expand All @@ -66,4 +68,42 @@ public function testFromResourceIds()
Linkage::fromManyResourceIds(new ResourceId('books', 'abc'), new ResourceId('squirrels', '123'))
);
}

public function testNullLinkageIsLinkedToNothing()
{
$apple = new ResourceId('apples', '1');
$this->assertFalse(Linkage::nullLinkage()->isLinkedTo($apple));
$this->assertFalse(Linkage::nullLinkage()->isLinkedTo(new NullData));
}

public function testEmptyArrayLinkageIsLinkedToNothing()
{
$apple = new ResourceId('apples', '1');
$this->assertFalse(Linkage::emptyArrayLinkage()->isLinkedTo($apple));
$this->assertFalse(Linkage::emptyArrayLinkage()->isLinkedTo(new NullData));
}

public function testSingleLinkageIsLinkedOnlyToItself()
{
$apple = new ResourceId('apples', '1');
$orange = new ResourceId('oranges', '1');

$linkage = Linkage::fromSingleResourceId($apple);

$this->assertTrue($linkage->isLinkedTo($apple));
$this->assertFalse($linkage->isLinkedTo($orange));
}

public function testMultiLinkageIsLinkedOnlyToItsMembers()
{
$apple = new ResourceId('apples', '1');
$orange = new ResourceId('oranges', '1');
$banana = new ResourceId('bananas', '1');

$linkage = Linkage::fromManyResourceIds($apple, $orange);

$this->assertTrue($linkage->isLinkedTo($apple));
$this->assertTrue($linkage->isLinkedTo($orange));
$this->assertFalse($linkage->isLinkedTo($banana));
}
}