diff --git a/src/PropertyHandler/DictionaryExporter.php b/src/PropertyHandler/DictionaryExporter.php index 8d350c9..5b1ef87 100644 --- a/src/PropertyHandler/DictionaryExporter.php +++ b/src/PropertyHandler/DictionaryExporter.php @@ -6,6 +6,7 @@ use Crell\Serde\Attributes\DictionaryField; use Crell\Serde\Attributes\Field; +use Crell\Serde\Attributes\SequenceField; use Crell\Serde\CollectionItem; use Crell\Serde\Deserializer; use Crell\Serde\Dict; @@ -60,8 +61,12 @@ protected function iteratorToDict(iterable $value, Field $field): Dict public function canExport(Field $field, mixed $value, string $format): bool { - return ($field->phpType === 'array' && !\array_is_list($value)) - || ($field->typeCategory === TypeCategory::Generator && $field->typeField instanceof DictionaryField); + return match (true) { + $field->typeField instanceof DictionaryField => true, + $field->typeField instanceof SequenceField => false, + $field->phpType === 'array' && !array_is_list($value) => true, + default => false, + }; } public function importValue(Deserializer $deserializer, Field $field, mixed $source): mixed diff --git a/src/PropertyHandler/SequenceExporter.php b/src/PropertyHandler/SequenceExporter.php index aeb58dc..8fbaae6 100644 --- a/src/PropertyHandler/SequenceExporter.php +++ b/src/PropertyHandler/SequenceExporter.php @@ -4,6 +4,7 @@ namespace Crell\Serde\PropertyHandler; +use Crell\Serde\Attributes\DictionaryField; use Crell\Serde\Attributes\Field; use Crell\Serde\Attributes\SequenceField; use Crell\Serde\CollectionItem; @@ -43,8 +44,12 @@ protected function iterableToSequence(iterable $value): Sequence public function canExport(Field $field, mixed $value, string $format): bool { - return ($field->phpType === 'array' && \array_is_list($value)) - || ($field->typeCategory === TypeCategory::Generator && $field->typeField instanceof SequenceField); + return match (true) { + $field->typeField instanceof SequenceField => true, + $field->typeField instanceof DictionaryField => false, + $field->phpType === 'array' && array_is_list($value) => true, + default => false, + }; } public function importValue(Deserializer $deserializer, Field $field, mixed $source): mixed diff --git a/tests/SequenceExporterTest.php b/tests/SequenceExporterTest.php new file mode 100644 index 0000000..71bcddf --- /dev/null +++ b/tests/SequenceExporterTest.php @@ -0,0 +1,137 @@ +assertEquals($expected, $exporter->canExport($field, $value, 'array')); + } + + public static function canExportExamples(): iterable + { + $sequenceArrayField = Field::create('test', phpType: 'array', typeField: new SequenceField()); + yield 'flagged sequence, array, empty' => [ + 'field' => $sequenceArrayField, + 'value' => [], + 'expected' => true, + ]; + yield 'flagged sequence, array, list' => [ + 'field' => $sequenceArrayField, + 'value' => ['a', 'b', 'c'], + 'expected' => true, + ]; + yield 'flagged sequence, array, map' => [ + 'field' => $sequenceArrayField, + 'value' => ['a' => 'A', 'b' => 'B', 'c' => 'C'], + 'expected' => true, + ]; + + $sequenceIterableField = Field::create('test', phpType: 'iterable', typeField: new SequenceField()); + yield 'flagged sequence, iterable, empty' => [ + 'field' => $sequenceIterableField, + 'value' => [], + 'expected' => true, + ]; + yield 'flagged sequence, iterable, list' => [ + 'field' => $sequenceIterableField, + 'value' => ['a', 'b', 'c'], + 'expected' => true, + ]; + yield 'flagged sequence, iterable, map' => [ + 'field' => $sequenceIterableField, + 'value' => ['a' => 'A', 'b' => 'B', 'c' => 'C'], + 'expected' => true, + ]; + + $nonArrayField = Field::create('test', phpType: 'float'); + yield 'unflagged, non-array, map' => [ + 'field' => $nonArrayField, + 'value' => ['a' => 'A', 'b' => 'B', 'c' => 'C'], + 'expected' => false, + ]; + + $dictionaryField = Field::create('test', phpType: 'array', typeField: new DictionaryField()); + yield 'flagged dictionary, array, empty' => [ + 'field' => $dictionaryField, + 'value' => [], + 'expected' => false, + ]; + yield 'flagged dictionary, array, list' => [ + 'field' => $dictionaryField, + 'value' => ['a', 'b', 'c'], + 'expected' => false, + ]; + yield 'flagged dictionary, array, map' => [ + 'field' => $dictionaryField, + 'value' => ['a' => 'A', 'b' => 'B', 'c' => 'C'], + 'expected' => false, + ]; + + $unmarkedArrayField = Field::create('test', phpType: 'array'); + yield 'unflagged, array, list' => [ + 'field' => $unmarkedArrayField, + 'value' => ['a', 'b', 'c'], + 'expected' => true, + ]; + yield 'unflagged, array, map' => [ + 'field' => $unmarkedArrayField, + 'value' => ['a' => 'A', 'b' => 'B', 'c' => 'C'], + 'expected' => false, + ]; + } + + #[Test, DataProvider('canImportExamples')] + public function can_import_the_right_values(Field $field, bool $expected): void + { + $exporter = new SequenceExporter(); + $this->assertEquals($expected, $exporter->canImport($field, 'array')); + } + + public static function canImportExamples(): iterable + { + $sequenceArrayField = Field::create('test', phpType: 'array', typeField: new SequenceField()); + yield 'flagged sequence, array' => [ + 'field' => $sequenceArrayField, + 'expected' => true, + ]; + + $sequenceIterableField = Field::create('test', phpType: 'iterable', typeField: new SequenceField()); + yield 'flagged sequence, iterable' => [ + 'field' => $sequenceIterableField, + 'expected' => true, + ]; + + $nonArrayField = Field::create('test', phpType: 'float'); + yield 'unflagged, non-array, map' => [ + 'field' => $nonArrayField, + 'expected' => false, + ]; + + $dictionaryField = Field::create('test', phpType: 'array', typeField: new DictionaryField()); + yield 'flagged dictionary, array' => [ + 'field' => $dictionaryField, + 'expected' => false, + ]; + + $unmarkedArrayField = Field::create('test', phpType: 'array'); + yield 'unflagged, array' => [ + 'field' => $unmarkedArrayField, + 'expected' => true, + ]; + } + +}