Skip to content

Commit

Permalink
Fix creation context issue
Browse files Browse the repository at this point in the history
Add failing test about nested collection lazy
  • Loading branch information
Tofandel committed Apr 15, 2024
1 parent 0b04846 commit 7551c3e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Laravel-data 4.0.0 was released 5 hours ago, time for an update!

- Make ValidationPath Stringable
- Fix PHPStan
- Improve performance when optional peoperty exists (#612)
- Improve performance when optional property exists (#612)

## 3.10.0 - 2023-12-01

Expand Down
6 changes: 5 additions & 1 deletion src/DataPipes/CastPropertiesDataPipe.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ protected function cast(
) {
$context = $creationContext->next($property->type->dataClass, $property->name);

return $property->type->kind->isDataObject()
$data = $property->type->kind->isDataObject()
? $context->from($value)
: $context->collect($value, $property->type->iterableClass);

$creationContext->previous();

return $data;
}

if (
Expand Down
61 changes: 61 additions & 0 deletions tests/CreationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\ValidationException;

use Spatie\LaravelData\DataPipeline;
use Spatie\LaravelData\DataPipes\DataPipe;
use Spatie\LaravelData\Support\Creation\CreationContext;
use Spatie\LaravelData\Support\DataClass;
use function Pest\Laravel\postJson;

use Spatie\LaravelData\Attributes\Computed;
Expand Down Expand Up @@ -1067,3 +1071,60 @@ public function __invoke(SimpleData $data)
->toBeArray()
->toEqual(['a', 'collection']);
})->skip(fn () => config('data.features.cast_and_transform_iterables') === false);

it('keeps the creation context path up to date', function () {
global $testCreationContexts;
$testCreationContexts = [];
class TestDataPipe implements DataPipe
{
public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array
{
global $testCreationContexts;
$testCreationContexts[] = clone $creationContext;

return $properties;
}
}
class TestNestedDataPipe implements DataPipe
{
public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array
{
global $testCreationContexts;
$testCreationContexts[] = clone $creationContext;

return $properties;
}
}

class SimpleDataWithTestPipe extends SimpleData
{
public static function pipeline(): DataPipeline
{
return parent::pipeline()
->through(TestNestedDataPipe::class);
}
}

$dataClass = new class () extends Data {
#[DataCollectionOf(SimpleDataWithTestPipe::class)]
public Collection $collection;

public static function pipeline(): DataPipeline
{
return parent::pipeline()
->through(TestDataPipe::class);
}
};

$dataClass::from([
'collection' => [['string' => 'no'], 'models', ['string' => 'here']],
]);

expect($testCreationContexts)->toHaveCount(3);
expect($testCreationContexts[0])->toBeInstanceOf(CreationContext::class);

expect($testCreationContexts[0]->currentPath)->toBe([0 => 'collection', 1 => 0]);
expect($testCreationContexts[1]->currentPath)->toBe([0 => 'collection', 1 => 2]);
expect($testCreationContexts[2]->currentPath)->toHaveCount(0);

});
26 changes: 26 additions & 0 deletions tests/PartialsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,32 @@
]);
});

it('can conditionally include nested collection', function () {
$dataClass = new class () extends Data {
#[DataCollectionOf(MultiLazyData::class)]
public Collection $nested;
};

$data = $dataClass::collect([
[
'nested' => [DummyDto::rick()],
], [
'nested' => [DummyDto::bon()],
]
], DataCollection::class);

expect($data->toArray())->toMatchArray([
['nested' => [[]]],
['nested' => [[]]]
]);

expect($data->include('nested.{artist,year}')->toArray())
->toMatchArray([
['nested' => [['artist' => DummyDto::rick()->artist, 'year' => DummyDto::rick()->year]]],
['nested' => [['artist' => DummyDto::bon()->artist, 'year' => DummyDto::bon()->year]]]
]);
});

it('can conditionally include using class defaults', function () {
PartialClassConditionalData::setDefinitions(includeDefinitions: [
'string' => fn (PartialClassConditionalData $data) => $data->enabled,
Expand Down

0 comments on commit 7551c3e

Please sign in to comment.