Skip to content
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

[BREAKING] Fix empty param bag #82

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion src/Fractal.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ public function createData()
$this->manager->parseFieldsets($this->fieldsets);
}

return $this->manager->createData($this->getResource(), $this->resourceName);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual fix.
The rest are just tests 😬

return $this->manager->createData($this->getResource());
}

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Spatie\Fractalistic\Fractal;
use Spatie\Fractalistic\Test\TestClasses\Author;
use Spatie\Fractalistic\Test\TestClasses\Book;
use Spatie\Fractalistic\Test\TestClasses\Character;
use Spatie\Fractalistic\Test\TestClasses\Publisher;

uses()
Expand Down Expand Up @@ -56,6 +57,11 @@ function getTestPublishers(): array
$authorA = new Author('Philip K Dick', '[email protected]');
$authorB = new Author('George R. R. Satan', '[email protected]');

$charA = new Character('Death');
$charB = new Character('Hex');
$charC = new Character('Ned Stark');
$charD = new Character('Tywin Lannister');

$bookA = new Book(
'1',
'Hogfather',
Expand All @@ -78,11 +84,19 @@ function getTestPublishers(): array

$bookA->author = $authorA;
$bookA->publisher = $publisherA;
$bookA->characters = [$charA, $charB];
$authorA->characters = [$charA, $charB];
$charA->book = $bookA;
$charB->book = $bookA;
$publisherA->books = [$bookA];
$authorA->books = [$bookA];

$bookB->author = $authorB;
$bookB->publisher = $publisherB;
$bookB->characters = [$charC, $charD];
$authorB->characters = [$charC, $charD];
$charC->book = $bookB;
$charD->book = $bookB;
$publisherB->books = [$bookB];
$authorB->books = [$bookB];

Expand Down
171 changes: 163 additions & 8 deletions tests/ScopeTest.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,168 @@
<?php

use Spatie\Fractalistic\Test\TestClasses\TestTransformer;
use function PHPUnit\Framework\assertEquals;
use League\Fractal\ParamBag;
use Spatie\Fractalistic\Fractal;
use Spatie\Fractalistic\Test\TestClasses\PublisherTransformer;

it('uses an identifier for the scope', function () {
$scope = $this->fractal
->collection($this->testBooks, new TestTransformer(), 'books')
->parseIncludes('characters')
->createData();
it('can parse include parameters', function ($resourceName, string $include, string $includeWithParams, ParamBag $expected): void {
$fractal = Fractal::create(getTestPublishers(), new PublisherTransformer())
->withResourceName($resourceName)
->parseIncludes($includeWithParams);

assertEquals('books', $scope->getIdentifier());
$scope = $fractal->createData();

$identifier = $scope->getIdentifier($include);
$actualParams = $scope->getManager()->getIncludeParams($identifier);
expect($actualParams)->toEqual($expected);
})->with([
[
'resource name: string' => 'Publisher',
],
[
'resource name: null' => null,
],
])->with([
[
'include' => 'books',
'include_with_params' => 'books:test(2|value)',
'expected' => new ParamBag([
'test' => ['2', 'value'],
]),
],
[
'include' => 'books',
'include_with_params' => 'books:test(another_value|3):another(1|2|3)',
'expected' => new ParamBag([
'test' => ['another_value', '3'],
'another' => ['1', '2', '3'],
]),
],
[
'include' => 'books.author',
'include_with_params' => 'books.author:test(test|value)',
'expected' => new ParamBag([
'test' => ['test', 'value'],
]),
],
]);

it('can access scope in transformer', function (): void {
$fractal = Fractal::create(getTestPublishers(), new PublisherTransformer())
->parseIncludes('books.characters,books.author.characters');

$result = $fractal->toArray();

expect($result)->toEqual([
'data' => [
[
'name' => 'Elephant books',
'address' => 'Amazon rainforests, near the river',
'books' =>
[
'data' => [
[
'id' => 1,
'title' => 'Hogfather',
'characters' => [
'data' => [
[
'name' => 'Death',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
[
'name' => 'Hex',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
]
],
'author' => [
'data' => [
'name' => 'Philip K Dick',
'email' => '[email protected]',
'characters' => [
'data' => [
[
'name' => 'Death',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
[
'name' => 'Hex',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
]
],
]
],
],
],
],
],
[
'name' => 'Bloody Fantasy inc.',
'address' => 'Diagon Alley, before the bank, to the left',
'books' => [
'data' => [
[
'id' => 2,
'title' => 'Game Of Kill Everyone',
'characters' => [
'data' => [
[
'name' => 'Ned Stark',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
[
'name' => 'Tywin Lannister',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
]
],
'author' => [
'data' => [
'name' => 'George R. R. Satan',
'email' => '[email protected]',
'characters' => [
'data' => [
[
'name' => 'Ned Stark',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
[
'name' => 'Tywin Lannister',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
]
],
],
]
],
],
],
],
],
]);
});
7 changes: 7 additions & 0 deletions tests/TestClasses/Author.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Author
public string $email;
/** @var Book[] */
public ?array $books = [];
/** @var Character[] */
public array $characters = [];

public function __construct(string $name, string $email)
{
Expand All @@ -19,4 +21,9 @@ public function books(): array
{
return $this->books;
}

public function characters(): array
{
return $this->characters;
}
}
6 changes: 6 additions & 0 deletions tests/TestClasses/AuthorTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AuthorTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'books',
'characters'
];

public function transform(Author $author): array
Expand All @@ -23,4 +24,9 @@ public function includeBooks(Author $author): Collection
{
return $this->collection($author->books(), new BookTransformer());
}

public function includeCharacters(Author $author): Collection
{
return $this->collection($author->characters(), new CharacterTransformer());
}
}
10 changes: 10 additions & 0 deletions tests/TestClasses/Book.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Book
public string $id;
public string $title;
public string $yr;
/** @var Character[] */
public array $characters = [];
public ?Publisher $publisher = null;
public ?Author $author = null;

Expand All @@ -25,6 +27,14 @@ public function publisher(): ?Publisher
return $this->publisher;
}

/**
* @return Character[]
*/
public function characters(): array
{
return $this->characters;
}

public function author(): ?Author
{
return $this->author;
Expand Down
7 changes: 7 additions & 0 deletions tests/TestClasses/BookTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace Spatie\Fractalistic\Test\TestClasses;

use League\Fractal\Resource\Collection;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;

class BookTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'publisher',
'characters',
'author',
];

Expand All @@ -25,6 +27,11 @@ public function includePublisher(Book $book): Item
return $this->item($book->publisher(), new PublisherTransformer());
}

public function includeCharacters(Book $book): Collection
{
return $this->collection($book->characters(), new CharacterTransformer());
}

public function includeAuthor(Book $book): Item
{
return $this->item($book->author(), new AuthorTransformer());
Expand Down
19 changes: 19 additions & 0 deletions tests/TestClasses/Character.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Spatie\Fractalistic\Test\TestClasses;

class Character
{
public string $name;
public ?Book $book = null;

public function __construct(string $name)
{
$this->name = $name;
}

public function book(): ?Book
{
return $this->book;
}
}
40 changes: 40 additions & 0 deletions tests/TestClasses/CharacterTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Spatie\Fractalistic\Test\TestClasses;

use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;

final class CharacterTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'book',
'author',
];

public function transform(Character $character): array
{
$parentScope = last($this->getCurrentScope()->getParentScopes());
$data = [
'name' => $character->name,
'current_scope' => $this->getCurrentScope()->getScopeIdentifier(),
'parent_scope' => $parentScope,
'scope_identifier' => $this->getCurrentScope()->getIdentifier(),
];

if ($parentScope === 'author') {
$data['called_by_author'] = 'indeed!';
}

if ($parentScope === 'books') {
$data['called_by_book'] = 'yes!';
}
Comment on lines +25 to +31
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can see, we are returnning different fields based on the context that we are in.
In the author context we return, called_by_author field, and
In the books context we return, called_by_book field.
It seems this is the reult that #39 wanted to achiev.


return $data;
}

public function includeBook(Character $character): Item
{
return $this->item($character->book(), new BookTransformer());
}
}
Loading