diff --git a/docs/advanced-usage/creating-a-cast.md b/docs/advanced-usage/creating-a-cast.md index fe0cc75a4..be6e09122 100644 --- a/docs/advanced-usage/creating-a-cast.md +++ b/docs/advanced-usage/creating-a-cast.md @@ -1,6 +1,6 @@ --- title: Creating a cast -weight: 8 +weight: 6 --- Casts take simple values and cast them into complex types. For example, `16-05-1994T00:00:00+00` could be cast into a `Carbon` object with the same date. diff --git a/docs/advanced-usage/creating-a-rule-inferrer.md b/docs/advanced-usage/creating-a-rule-inferrer.md index a37bb106d..10a39b5f4 100644 --- a/docs/advanced-usage/creating-a-rule-inferrer.md +++ b/docs/advanced-usage/creating-a-rule-inferrer.md @@ -1,6 +1,6 @@ --- title: Creating a rule inferrer -weight: 10 +weight: 8 --- Rule inferrers will try to infer validation rules for properties within a data object. diff --git a/docs/advanced-usage/creating-a-transformer.md b/docs/advanced-usage/creating-a-transformer.md index 95660b774..397ec8351 100644 --- a/docs/advanced-usage/creating-a-transformer.md +++ b/docs/advanced-usage/creating-a-transformer.md @@ -1,6 +1,6 @@ --- title: Creating a transformer -weight: 9 +weight: 7 --- Transformers take complex values and transform them into simple types. For example, a `Carbon` object could be transformed to `16-05-1994T00:00:00+00`. @@ -10,10 +10,18 @@ A transformer implements the following interface: ```php interface Transformer { - public function transform(DataProperty $property, mixed $value): mixed; + public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed; } ``` -The value that should be transformed is given, and a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures). +The following parameters are provided: -In the end, the transformer should return a transformed value. Please note that the given value of a transformer can never be `null`. +- **property**: a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures) +- **value**: the value that should be transformed, this will never be `null` +- **context**: a `TransformationContext` object which contains the current transformation context with the following properties: + - **transformValues** indicates if values should be transformed or not + - **mapPropertyNames** indicates if property names should be mapped or not + - **wrapExecutionType** the execution type that should be used for wrapping values + - **transformers** a collection of transformers that can be used to transform values + +In the end, the transformer should return a transformed value. diff --git a/docs/advanced-usage/normalizers.md b/docs/advanced-usage/normalizers.md index 51507f20f..609c613bb 100644 --- a/docs/advanced-usage/normalizers.md +++ b/docs/advanced-usage/normalizers.md @@ -20,6 +20,10 @@ By default, there are five normalizers for each data object: - **ArrayNormalizer** will cast arrays - **JsonNormalizer** will cast json strings +A sixth normalizer can be optionally enabled: + +- **FormRequestNormalizer** will normalize a form request by calling the `validated` method + Normalizers can be globally configured in `config/data.php`, and can be configured on a specific data object by overriding the `normalizers` method. ```php diff --git a/docs/advanced-usage/pipeline.md b/docs/advanced-usage/pipeline.md index 333e11b1e..f3f1aafbe 100644 --- a/docs/advanced-usage/pipeline.md +++ b/docs/advanced-usage/pipeline.md @@ -14,6 +14,7 @@ By default, the pipeline exists of the following pipes: - **AuthorizedDataPipe** checks if the user is authorized to perform the request - **MapPropertiesDataPipe** maps the names of properties +- **FillRouteParameterPropertiesDataPipe** fills property values from route parameters - **ValidatePropertiesDataPipe** validates the properties - **DefaultValuesDataPipe** adds default values for properties when they are not set - **CastPropertiesDataPipe** casts the values of properties @@ -35,6 +36,7 @@ class SongData extends Data ->into(static::class) ->through(AuthorizedDataPipe::class) ->through(MapPropertiesDataPipe::class) + ->through(FillRouteParameterPropertiesDataPipe::class) ->through(ValidatePropertiesDataPipe::class) ->through(DefaultValuesDataPipe::class) ->through(CastPropertiesDataPipe::class); @@ -42,12 +44,12 @@ class SongData extends Data } ``` -Each pipe implements the `DataPipe` interface and should return a `Collection` of properties: +Each pipe implements the `DataPipe` interface and should return an `array` of properties: ```php interface DataPipe { - public function handle(mixed $payload, DataClass $class, Collection $properties): Collection; + public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array; } ``` @@ -57,6 +59,13 @@ The `handle` method has several arguments: - **class** the `DataClass` object for the data object [more info](/docs/laravel-data/v4/advanced-usage/internal-structures) - **properties** the key-value properties which will be used to construct the data object +- **creationContext** the context in which the data object is being created you'll find the following info here: + - **dataClass** the data class which is being created + - **validationStrategy** the validation strategy which is being used + - **mapPropertyNames** whether property names should be mapped + - **withoutMagicalCreation** whether to use the magical creation methods or not + - **ignoredMagicalMethods** the magical methods which are ignored + - **casts** a collection of global casts When using a magic creation methods, the pipeline is not being used (since you manually overwrite how a data object is constructed). Only when you pass in a request object a minimal version of the pipeline is used to authorize and validate diff --git a/docs/advanced-usage/typescript.md b/docs/advanced-usage/typescript.md index 66e5d29a4..08de76034 100644 --- a/docs/advanced-usage/typescript.md +++ b/docs/advanced-usage/typescript.md @@ -128,19 +128,3 @@ class DataObject extends Data } } ``` - -You can also make all the properties of a data object optional in TypeScript like this: - -```php -class DataObject extends Data -{ - #[TypeScriptOptional] - public function __construct( - public int $id, - public string $someString, - public Optional|string $optional, - ) - { - } -} -``` diff --git a/docs/advanced-usage/use-with-inertia.md b/docs/advanced-usage/use-with-inertia.md index ada92a266..4f7162e00 100644 --- a/docs/advanced-usage/use-with-inertia.md +++ b/docs/advanced-usage/use-with-inertia.md @@ -1,6 +1,6 @@ --- title: Use with Inertia -weight: 6 +weight: 9 --- > Inertia.js lets you quickly build modern single-page React, Vue, and Svelte apps using classic server-side routing and controllers. diff --git a/docs/advanced-usage/use-with-livewire.md b/docs/advanced-usage/use-with-livewire.md index ac832b89e..57d528a3a 100644 --- a/docs/advanced-usage/use-with-livewire.md +++ b/docs/advanced-usage/use-with-livewire.md @@ -1,6 +1,6 @@ --- title: Use with Livewire -weight: 7 +weight: 10 --- > Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple without leaving the comfort of Laravel. diff --git a/docs/advanced-usage/validation-attributes.md b/docs/advanced-usage/validation-attributes.md index 58eb28caf..25d0a6cfb 100644 --- a/docs/advanced-usage/validation-attributes.md +++ b/docs/advanced-usage/validation-attributes.md @@ -1,6 +1,6 @@ --- title: Validation attributes -weight: 16 +weight: 14 --- These are all the validation attributes currently available in laravel-data. diff --git a/docs/advanced-usage/working-with-dates.md b/docs/advanced-usage/working-with-dates.md index 0ae42544c..1cd576021 100644 --- a/docs/advanced-usage/working-with-dates.md +++ b/docs/advanced-usage/working-with-dates.md @@ -54,7 +54,7 @@ within the `data.php` config file: Now when casting a date, a valid format will be searched. When none can be found, an exception is thrown. -When a transformers hasn't explicitly stated it's format, the first format within the array is used. +When a transformers hasn't explicitly stated its format, the first format within the array is used. ## Casting dates in a different time zone diff --git a/docs/as-a-resource/transformers.md b/docs/as-a-resource/transformers.md index 779b4aef3..1d678e60e 100644 --- a/docs/as-a-resource/transformers.md +++ b/docs/as-a-resource/transformers.md @@ -101,7 +101,7 @@ It is possible to disable the transformation of values, which will make the `tra use Spatie\LaravelData\Support\Transformation\TransformationContext; ArtistData::from($artist)->transform( - TransformationContext::create()->withoutTransformingValues() + TransformationContextFactory::create()->transformValues(false) ); ``` @@ -118,7 +118,7 @@ The [mapping of property names](/docs/laravel-data/v4/as-a-resource/mapping-prop ```php ArtistData::from($artist)->transform( - TransformationContext::create()->mapPropertyNames(false) + TransformationContextFactory::create()->mapPropertyNames(false) ); ``` @@ -128,7 +128,7 @@ It is possible to enable [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping use Spatie\LaravelData\Support\Wrapping\WrapExecutionType; ArtistData::from($artist)->transform( - TransformationContext::create()->wrapExecutionType(WrapExecutionType::Enabled) + TransformationContextFactory::create()->wrapExecutionType(WrapExecutionType::Enabled) ); ``` diff --git a/src/Concerns/BaseDataCollectable.php b/src/Concerns/BaseDataCollectable.php index 4b90d5db8..e1041b6f6 100644 --- a/src/Concerns/BaseDataCollectable.php +++ b/src/Concerns/BaseDataCollectable.php @@ -24,7 +24,7 @@ public function getDataClass(): string public function getIterator(): ArrayIterator { /** @var array $data */ - $data = $this->transform(TransformationContextFactory::create()->transformValues(false)); + $data = $this->transform(TransformationContextFactory::create()->withValueTransformation(false)); return new ArrayIterator($data); } diff --git a/src/Concerns/ResponsableData.php b/src/Concerns/ResponsableData.php index 1371809f7..335785442 100644 --- a/src/Concerns/ResponsableData.php +++ b/src/Concerns/ResponsableData.php @@ -15,7 +15,7 @@ trait ResponsableData public function toResponse($request) { $contextFactory = TransformationContextFactory::create() - ->wrapExecutionType(WrapExecutionType::Enabled); + ->withWrapExecutionType(WrapExecutionType::Enabled); $includePartials = DataContainer::get()->requestQueryStringPartialsResolver()->execute( $this, diff --git a/src/Concerns/TransformableData.php b/src/Concerns/TransformableData.php index 09ffe7c63..255d488b8 100644 --- a/src/Concerns/TransformableData.php +++ b/src/Concerns/TransformableData.php @@ -37,7 +37,7 @@ public function transform( public function all(): array { - return $this->transform(TransformationContextFactory::create()->transformValues(false)); + return $this->transform(TransformationContextFactory::create()->withValueTransformation(false)); } public function toArray(): array diff --git a/src/DataPipes/DataPipe.php b/src/DataPipes/DataPipe.php index ceb7f64f0..5e411ce5a 100644 --- a/src/DataPipes/DataPipe.php +++ b/src/DataPipes/DataPipe.php @@ -8,17 +8,9 @@ interface DataPipe { /** - * @param mixed $payload - * @param DataClass $class * @param array $properties - * @param CreationContext $creationContext * * @return array */ - public function handle( - mixed $payload, - DataClass $class, - array $properties, - CreationContext $creationContext - ): array; + public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array; } diff --git a/src/Support/Creation/CreationContext.php b/src/Support/Creation/CreationContext.php index 030b67097..570b4592c 100644 --- a/src/Support/Creation/CreationContext.php +++ b/src/Support/Creation/CreationContext.php @@ -16,7 +16,6 @@ use Spatie\LaravelData\CursorPaginatedDataCollection; use Spatie\LaravelData\DataCollection; use Spatie\LaravelData\PaginatedDataCollection; -use Spatie\LaravelData\Support\Casting\GlobalCastsCollection; use Spatie\LaravelData\Support\DataContainer; /** diff --git a/src/Support/Creation/CreationContextFactory.php b/src/Support/Creation/CreationContextFactory.php index f630a4094..4dad0b1e8 100644 --- a/src/Support/Creation/CreationContextFactory.php +++ b/src/Support/Creation/CreationContextFactory.php @@ -17,7 +17,6 @@ use Spatie\LaravelData\CursorPaginatedDataCollection; use Spatie\LaravelData\DataCollection; use Spatie\LaravelData\PaginatedDataCollection; -use Spatie\LaravelData\Support\Casting\GlobalCastsCollection; use Spatie\LaravelData\Support\DataContainer; /** @@ -32,7 +31,7 @@ public function __construct( public string $dataClass, public ValidationStrategy $validationStrategy, public bool $mapPropertyNames, - public bool $withoutMagicalCreation, + public bool $disableMagicalCreation, public ?array $ignoredMagicalMethods, public ?GlobalCastsCollection $casts, ) { @@ -48,25 +47,12 @@ public static function createFromConfig( dataClass: $dataClass, validationStrategy: ValidationStrategy::from($config['validation_strategy']), mapPropertyNames: true, - withoutMagicalCreation: false, + disableMagicalCreation: false, ignoredMagicalMethods: null, casts: null, ); } - public static function createFromContext( - CreationContext $context - ) { - return new self( - dataClass: $context->dataClass, - validationStrategy: $context->validationStrategy, - mapPropertyNames: $context->mapPropertyNames, - withoutMagicalCreation: $context->withoutMagicalCreation, - ignoredMagicalMethods: $context->ignoredMagicalMethods, - casts: $context->casts, - ); - } - public function validationStrategy(ValidationStrategy $validationStrategy): self { $this->validationStrategy = $validationStrategy; @@ -95,6 +81,13 @@ public function alwaysValidate(): self return $this; } + public function withPropertyNameMapping(bool $withPropertyNameMapping = true): self + { + $this->mapPropertyNames = $withPropertyNameMapping; + + return $this; + } + public function withoutPropertyNameMapping(bool $withoutPropertyNameMapping = true): self { $this->mapPropertyNames = ! $withoutPropertyNameMapping; @@ -104,7 +97,14 @@ public function withoutPropertyNameMapping(bool $withoutPropertyNameMapping = tr public function withoutMagicalCreation(bool $withoutMagicalCreation = true): self { - $this->withoutMagicalCreation = $withoutMagicalCreation; + $this->disableMagicalCreation = $withoutMagicalCreation; + + return $this; + } + + public function withMagicalCreation(bool $withMagicalCreation = true): self + { + $this->disableMagicalCreation = ! $withMagicalCreation; return $this; } @@ -157,7 +157,7 @@ public function get(): CreationContext dataClass: $this->dataClass, validationStrategy: $this->validationStrategy, mapPropertyNames: $this->mapPropertyNames, - withoutMagicalCreation: $this->withoutMagicalCreation, + withoutMagicalCreation: $this->disableMagicalCreation, ignoredMagicalMethods: $this->ignoredMagicalMethods, casts: $this->casts, ); diff --git a/src/Support/Casting/GlobalCastsCollection.php b/src/Support/Creation/GlobalCastsCollection.php similarity index 96% rename from src/Support/Casting/GlobalCastsCollection.php rename to src/Support/Creation/GlobalCastsCollection.php index 50eabb700..9a4a311fd 100644 --- a/src/Support/Casting/GlobalCastsCollection.php +++ b/src/Support/Creation/GlobalCastsCollection.php @@ -1,6 +1,6 @@ transformers[get_debug_type($value)] ?? null; } foreach ($this->transformers as $transformable => $transformer) { diff --git a/src/Support/Transformation/TransformationContextFactory.php b/src/Support/Transformation/TransformationContextFactory.php index 61bddd0d3..45798c4ee 100644 --- a/src/Support/Transformation/TransformationContextFactory.php +++ b/src/Support/Transformation/TransformationContextFactory.php @@ -94,87 +94,65 @@ public function get( ); } - public function transformValues(bool $transformValues = true): static + public function withValueTransformation(bool $transformValues = true): static { $this->transformValues = $transformValues; return $this; } - public function mapPropertyNames(bool $mapPropertyNames = true): static + public function withoutValueTransformation(bool $withoutValueTransformation = true): static { - $this->mapPropertyNames = $mapPropertyNames; + $this->transformValues = ! $withoutValueTransformation; return $this; } - public function wrapExecutionType(WrapExecutionType $wrapExecutionType): static + public function withPropertyNameMapping(bool $mapPropertyNames = true): static { - $this->wrapExecutionType = $wrapExecutionType; + $this->mapPropertyNames = $mapPropertyNames; return $this; } - public function transformer(string $transformable, Transformer $transformer): static + public function withoutPropertyNameMapping(bool $withoutPropertyNameMapping = true): static { - if ($this->transformers === null) { - $this->transformers = new GlobalTransformersCollection(); - } - - $this->transformers->add($transformable, $transformer); + $this->mapPropertyNames = ! $withoutPropertyNameMapping; return $this; } - public function addIncludePartial(Partial ...$partial): static + public function withWrapExecutionType(WrapExecutionType $wrapExecutionType): static { - if ($this->includePartials === null) { - $this->includePartials = new PartialsCollection(); - } - - foreach ($partial as $include) { - $this->includePartials->attach($include); - } + $this->wrapExecutionType = $wrapExecutionType; return $this; } - public function addExcludePartial(Partial ...$partial): static + public function withoutWrapping(): static { - if ($this->excludePartials === null) { - $this->excludePartials = new PartialsCollection(); - } - - foreach ($partial as $exclude) { - $this->excludePartials->attach($exclude); - } + $this->wrapExecutionType = WrapExecutionType::Disabled; return $this; } - public function addOnlyPartial(Partial ...$partial): static + public function withWrapping(): static { - if ($this->onlyPartials === null) { - $this->onlyPartials = new PartialsCollection(); - } - - foreach ($partial as $only) { - $this->onlyPartials->attach($only); - } + $this->wrapExecutionType = WrapExecutionType::Enabled; return $this; } - public function addExceptPartial(Partial ...$partial): static + public function withTransformer(string $transformable, Transformer|string $transformer): static { - if ($this->exceptPartials === null) { - $this->exceptPartials = new PartialsCollection(); - } + $transformer = is_string($transformer) ? app($transformer) : $transformer; - foreach ($partial as $except) { - $this->exceptPartials->attach($except); + if ($this->transformers === null) { + $this->transformers = new GlobalTransformersCollection(); } + $this->transformers->add($transformable, $transformer); + return $this; } diff --git a/tests/CreationFactoryTest.php b/tests/CreationFactoryTest.php index 985d7f173..c512024ce 100644 --- a/tests/CreationFactoryTest.php +++ b/tests/CreationFactoryTest.php @@ -5,7 +5,7 @@ use Spatie\LaravelData\Attributes\MapInputName; use Spatie\LaravelData\Attributes\Validation\In; use Spatie\LaravelData\Data; -use Spatie\LaravelData\Support\Casting\GlobalCastsCollection; +use Spatie\LaravelData\Support\Creation\GlobalCastsCollection; use Spatie\LaravelData\Tests\Fakes\Casts\MeaningOfLifeCast; use Spatie\LaravelData\Tests\Fakes\Casts\StringToUpperCast; use Spatie\LaravelData\Tests\Fakes\SimpleData; diff --git a/tests/MappingTest.php b/tests/MappingTest.php index 74412fc72..ebc2c5a83 100644 --- a/tests/MappingTest.php +++ b/tests/MappingTest.php @@ -94,7 +94,7 @@ public function __construct( } }; - expect($data)->transform(TransformationContextFactory::create()->mapPropertyNames(false)) + expect($data)->transform(TransformationContextFactory::create()->withPropertyNameMapping(false)) ->toMatchArray([ 'camelName' => 'Freek', ]); diff --git a/tests/Support/Creation/CreationContextFactoryTest.php b/tests/Support/Creation/CreationContextFactoryTest.php new file mode 100644 index 000000000..b6b68f256 --- /dev/null +++ b/tests/Support/Creation/CreationContextFactoryTest.php @@ -0,0 +1,130 @@ +dataClass)->toBe(SimpleData::class); + expect($context->validationStrategy)->toBe(ValidationStrategy::from(config('data.validation_strategy'))); + expect($context->mapPropertyNames)->toBeTrue(); + expect($context->disableMagicalCreation)->toBeFalse(); + expect($context->ignoredMagicalMethods)->toBeNull(); + expect($context->casts)->toBeNull(); +}); + +it('is possible to override the validation strategy', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->validationStrategy(ValidationStrategy::OnlyRequests); + + expect($context->validationStrategy)->toBe(ValidationStrategy::OnlyRequests); +}); + +it('is possible to disable validation', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withoutValidation(); + + expect($context->validationStrategy)->toBe(ValidationStrategy::Disabled); +}); + +it('is possible to only validate requests', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->onlyValidateRequests(); + + expect($context->validationStrategy)->toBe(ValidationStrategy::OnlyRequests); +}); + +it('is possible to always validate', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->alwaysValidate(); + + expect($context->validationStrategy)->toBe(ValidationStrategy::Always); +}); + +it('is possible to disable property name mapping', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withoutPropertyNameMapping(); + + expect($context->mapPropertyNames)->toBeFalse(); +}); + +it('is possible to enable property name mapping', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withPropertyNameMapping(); + + expect($context->mapPropertyNames)->toBeTrue(); +}); + +it('is possible to disable magical creation', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withoutMagicalCreation(); + + expect($context->disableMagicalCreation)->toBeTrue(); +}); + +it('is possible to enable magical creation', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withMagicalCreation(); + + expect($context->disableMagicalCreation)->toBeFalse(); +}); + +it('is possible to set ignored magical methods', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->ignoreMagicalMethod('foo', 'bar'); + + expect($context->ignoredMagicalMethods)->toBe(['foo', 'bar']); +}); + +it('is possible to add a cast', function () { + $context = CreationContextFactory::createFromConfig( + SimpleData::class + )->withCast('string', StringToUpperCast::class); + + $dataClass = new class extends Data + { + public string $string; + }; + + $dataProperty = app(DataConfig::class)->getDataClass($dataClass::class)->properties['string']; + + expect($context->casts) + ->not()->toBeNull() + ->findCastForValue($dataProperty)->toBeInstanceOf(StringToUpperCast::class); +}); + +it('is possible to add a cast collection', function (){ + $context = CreationContextFactory::createFromConfig(SimpleData::class) + ->withCast(\Illuminate\Support\Stringable::class, StringToUpperCast::class) + ->withCastCollection(new GlobalCastsCollection([ + 'string' => new StringToUpperCast() + ])); + + $dataClass = new class extends Data + { + public string $string; + }; + + $dataProperty = app(DataConfig::class)->getDataClass($dataClass::class)->properties['string']; + + expect($context->casts) + ->not()->toBeNull() + ->findCastForValue($dataProperty)->toBeInstanceOf(StringToUpperCast::class); +}); diff --git a/tests/Support/Transformation/TransformationContextFactoryTest.php b/tests/Support/Transformation/TransformationContextFactoryTest.php new file mode 100644 index 000000000..dcb3e3a96 --- /dev/null +++ b/tests/Support/Transformation/TransformationContextFactoryTest.php @@ -0,0 +1,85 @@ +get( + SimpleData::from('Hello World') + ); + + expect($context)->toBeInstanceOf(TransformationContext::class); + expect($context->transformValues)->toBeTrue(); + expect($context->mapPropertyNames)->toBeTrue(); + expect($context->wrapExecutionType)->toBe(WrapExecutionType::Disabled); + expect($context->transformers)->toBeNull(); +}); + +it('can disable value transformation', function () { + $context = TransformationContextFactory::create() + ->withoutValueTransformation() + ->get(SimpleData::from('Hello World')); + + expect($context->transformValues)->toBeFalse(); +}); + +it('can enable value transformation', function () { + $context = TransformationContextFactory::create() + ->withValueTransformation() + ->get(SimpleData::from('Hello World')); + + expect($context->transformValues)->toBeTrue(); +}); + +it('can disable property name mapping', function () { + $context = TransformationContextFactory::create() + ->withoutPropertyNameMapping() + ->get(SimpleData::from('Hello World')); + + expect($context->mapPropertyNames)->toBeFalse(); +}); + +it('can enable property name mapping', function () { + $context = TransformationContextFactory::create() + ->withPropertyNameMapping() + ->get(SimpleData::from('Hello World')); + + expect($context->mapPropertyNames)->toBeTrue(); +}); + +it('can disable wrapping', function () { + $context = TransformationContextFactory::create() + ->withoutWrapping() + ->get(SimpleData::from('Hello World')); + + expect($context->wrapExecutionType)->toBe(WrapExecutionType::Disabled); +}); + +it('can enable wrapping', function () { + $context = TransformationContextFactory::create() + ->withWrapping() + ->get(SimpleData::from('Hello World')); + + expect($context->wrapExecutionType)->toBe(WrapExecutionType::Enabled); +}); + +it('can set a custom wrap execution type', function () { + $context = TransformationContextFactory::create() + ->withWrapExecutionType(WrapExecutionType::Enabled) + ->get(SimpleData::from('Hello World')); + + expect($context->wrapExecutionType)->toBe(WrapExecutionType::Enabled); +}); + +it('can add a custom transformers', function () { + $context = TransformationContextFactory::create() + ->withTransformer('string', StringToUpperTransformer::class) + ->get(SimpleData::from('Hello World')); + + expect($context->transformers)->not()->toBe(null); + expect($context->transformers->findTransformerForValue('Hello World'))->toBeInstanceOf(StringToUpperTransformer::class); +}); diff --git a/tests/TransformationTest.php b/tests/TransformationTest.php index 0dd8c7e0c..f2409a19c 100644 --- a/tests/TransformationTest.php +++ b/tests/TransformationTest.php @@ -311,7 +311,7 @@ public function transform(DataProperty $property, mixed $value, TransformationCo }; $transformed = $data->transform( - TransformationContextFactory::create()->transformer(DateTimeInterface::class, $customTransformer) + TransformationContextFactory::create()->withTransformer(DateTimeInterface::class, $customTransformer) ); expect($transformed)->toBe([