Commit af2d836f authored by Anton Smirnov's avatar Anton Smirnov
Browse files

Do not autoresolve serializable

parent b768dc76
Loading
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -19,7 +19,18 @@ trait IterableValueTrait
{
    private readonly Traversable $traversable;

    public function __construct(iterable|stdClass|Json5Serializable|JsonSerializable $iterable)
    public function __construct(iterable|stdClass $iterable)
    {
        if (\is_array($iterable)) {
            $iterable = new ArrayIterator($iterable);
        } elseif ($iterable instanceof stdClass) {
            $iterable = new ArrayObject($iterable);
        }

        $this->traversable = $iterable;
    }

    public static function fromSerializable(iterable|stdClass|Json5Serializable|JsonSerializable $iterable): self
    {
        start:

@@ -39,7 +50,25 @@ trait IterableValueTrait
            $iterable = new ArrayObject($iterable);
        }

        $this->traversable = $iterable;
        return new self($iterable);
    }

    public static function fromJsonSerializable(iterable|stdClass|JsonSerializable $iterable): self
    {
        start:

        if ($iterable instanceof JsonSerializable) {
            $iterable = $iterable->jsonSerialize();
            goto start; // restart parsing
        }

        if (\is_array($iterable)) {
            $iterable = new ArrayIterator($iterable);
        } elseif ($iterable instanceof stdClass) {
            $iterable = new ArrayObject($iterable);
        }

        return new self($iterable);
    }

    public function getIterator(): Generator
+0 −43
Original line number Diff line number Diff line
@@ -7,8 +7,6 @@ namespace Arokettu\Json5\Tests\Collections;
use Arokettu\Json5\Json5Encoder;
use Arokettu\Json5\JsonEncoder;
use Arokettu\Json5\Values\ArrayValue;
use Arokettu\Json5\Values\Json5Serializable;
use JsonSerializable;
use PHPUnit\Framework\TestCase;
use stdClass;

@@ -52,47 +50,6 @@ class ArrayValueTest extends TestCase
        self::assertStringEqualsFile(__DIR__ . '/data/array_value/array_value.json', JsonEncoder::encode($list));
    }

    public function testSupportJsonSerializable(): void
    {
        $class = new class implements JsonSerializable {
            public function jsonSerialize(): array
            {
                return [1,2,3,4];
            }
        };

        $list = new ArrayValue($class);

        self::assertStringEqualsFile(__DIR__ . '/data/array_value/array_value.json5', Json5Encoder::encode($list));
        self::assertStringEqualsFile(__DIR__ . '/data/array_value/array_value.json', JsonEncoder::encode($list));
    }

    public function testSupportJson5Serializable(): void
    {
        $class = new class implements JsonSerializable, Json5Serializable {
            public function json5Serialize(): array // takes precedence
            {
                return [1,2,3];
            }

            public function jsonSerialize(): array
            {
                return [4,5];
            }
        };

        // supported in JSON5
        self::assertStringEqualsFile(
            __DIR__ . '/data/array_value/array_value_serializable.json5',
            Json5Encoder::encode(new ArrayValue($class))
        );
        // not supported in JSON
        self::assertStringEqualsFile(
            __DIR__ . '/data/array_value/array_value_serializable.json',
            JsonEncoder::encode(new ArrayValue($class))
        );
    }

    public function testJsonTransparency(): void
    {
        // array that is not a list
+0 −41
Original line number Diff line number Diff line
@@ -7,10 +7,7 @@ namespace Arokettu\Json5\Tests\Collections;
use Arokettu\Json5\Json5Encoder;
use Arokettu\Json5\JsonEncoder;
use Arokettu\Json5\Values\CompactArray;
use Arokettu\Json5\Values\Json5Serializable;
use JsonSerializable;
use PHPUnit\Framework\TestCase;
use SplFixedArray;
use stdClass;

class CompactArrayTest extends TestCase
@@ -53,44 +50,6 @@ class CompactArrayTest extends TestCase
        self::assertStringEqualsFile(__DIR__ . '/data/compact_array/compact_array.json', JsonEncoder::encode($list));
    }

    public function testSupportJsonSerializable(): void
    {
        $arr = new SplFixedArray(4);
        $arr[0] = 1;
        $arr[1] = 2;
        $arr[2] = 3;
        $arr[3] = 4;

        $list = new CompactArray($arr);

        self::assertStringEqualsFile(__DIR__ . '/data/compact_array/compact_array.json5', Json5Encoder::encode($list));
        self::assertStringEqualsFile(__DIR__ . '/data/compact_array/compact_array.json', JsonEncoder::encode($list));
    }

    public function testSupportJson5Serializable(): void
    {
        $class = new class implements JsonSerializable, Json5Serializable {
            public function json5Serialize(): array // takes precedence
            {
                return [1,2,3];
            }

            public function jsonSerialize(): array
            {
                return [4,5];
            }
        };

        self::assertStringEqualsFile(
            __DIR__ . '/data/compact_array/compact_array_serializable.json5',
            Json5Encoder::encode(new CompactArray($class)),
        );
        self::assertStringEqualsFile(
            __DIR__ . '/data/compact_array/compact_array_serializable.json',
            JsonEncoder::encode(new CompactArray($class)),
        );
    }

    public function testCompactArrayOfObjects(): void
    {
        $list = new CompactArray([
+0 −39
Original line number Diff line number Diff line
@@ -7,10 +7,7 @@ namespace Arokettu\Json5\Tests\Collections;
use Arokettu\Json5\Json5Encoder;
use Arokettu\Json5\JsonEncoder;
use Arokettu\Json5\Values\CompactObject;
use Arokettu\Json5\Values\Json5Serializable;
use JsonSerializable;
use PHPUnit\Framework\TestCase;
use SplFixedArray;
use stdClass;

class CompactObjectTest extends TestCase
@@ -55,42 +52,6 @@ class CompactObjectTest extends TestCase
        self::assertStringEqualsFile(self::DATA_DIR . '/object_value_iterable.json', JsonEncoder::encode($obj));
    }

    public function testSupportJsonSerializable(): void
    {
        $arr = new SplFixedArray(4);
        $arr[0] = 1;
        $arr[1] = 2;
        $arr[2] = 3;
        $arr[3] = 4;

        $obj = new CompactObject($arr);
        self::assertStringEqualsFile(self::DATA_DIR . '/object_value_list.json5', Json5Encoder::encode($obj));

        $obj = new CompactObject($arr);
        self::assertStringEqualsFile(self::DATA_DIR . '/object_value_list.json', JsonEncoder::encode($obj));
    }

    public function testSupportJson5Serializable(): void
    {
        $class = new class implements JsonSerializable, Json5Serializable {
            public function json5Serialize(): array // takes precedence
            {
                return [1,2,3];
            }

            public function jsonSerialize(): array
            {
                return [4,5];
            }
        };

        $list = new CompactObject($class);
        self::assertStringEqualsFile(self::DATA_DIR . '/object_value_list_short.json5', Json5Encoder::encode($list));

        $list = new CompactObject($class);
        self::assertStringEqualsFile(self::DATA_DIR . '/object_value_list_short.json', JsonEncoder::encode($list));
    }

    public function testCompactObjectOfArrays(): void
    {
        $obj = new CompactObject([
+103 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Arokettu\Json5\Tests\Collections;

use Arokettu\Json5\Values\ArrayValue;
use Arokettu\Json5\Values\CompactArray;
use Arokettu\Json5\Values\CompactObject;
use Arokettu\Json5\Values\InlineArray;
use Arokettu\Json5\Values\InlineObject;
use Arokettu\Json5\Values\Json5Serializable;
use Arokettu\Json5\Values\ObjectValue;
use JsonSerializable;
use PHPUnit\Framework\TestCase;
use stdClass;

class FromSerializableTest extends TestCase
{
    public function testObjectsSupportJson5Serializable(): void
    {
        $class = new class implements Json5Serializable {
            public function json5Serialize(): array // takes precedence
            {
                return ['a' => 1, 'b' => 2, 'c' => 3];
            }
        };

        $object = $class->json5Serialize();

        self::assertEquals($object, iterator_to_array(ArrayValue::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactArray::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineArray::fromSerializable($class)));

        self::assertEquals($object, iterator_to_array(ObjectValue::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactObject::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineObject::fromSerializable($class)));
    }

    public function testObjectsSupportJsonSerializable(): void
    {
        $class = new class implements JsonSerializable {
            public function jsonSerialize(): array
            {
                return ['d' => 4, 'e' => 5];
            }
        };

        $object = $class->jsonSerialize();

        self::assertEquals($object, iterator_to_array(ArrayValue::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactArray::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineArray::fromSerializable($class)));

        self::assertEquals($object, iterator_to_array(ObjectValue::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactObject::fromSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineObject::fromSerializable($class)));

        self::assertEquals($object, iterator_to_array(ArrayValue::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactArray::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineArray::fromJsonSerializable($class)));

        self::assertEquals($object, iterator_to_array(ObjectValue::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactObject::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineObject::fromJsonSerializable($class)));
    }

    public function testJson5TakesPrecedence(): void
    {
        $class = new class implements JsonSerializable, Json5Serializable {
            public function json5Serialize(): stdClass // takes precedence
            {
                return (object)['a' => 1, 'b' => 2, 'c' => 3];
            }

            public function jsonSerialize(): stdClass
            {
                return (object)['d' => 4, 'e' => 5];
            }
        };

        $object = (array)$class->jsonSerialize();
        $object5 = (array)$class->json5Serialize();

        // JSON5 Serailizable
        self::assertEquals($object5, iterator_to_array(ArrayValue::fromSerializable($class)));
        self::assertEquals($object5, iterator_to_array(CompactArray::fromSerializable($class)));
        self::assertEquals($object5, iterator_to_array(InlineArray::fromSerializable($class)));

        self::assertEquals($object5, iterator_to_array(ObjectValue::fromSerializable($class)));
        self::assertEquals($object5, iterator_to_array(CompactObject::fromSerializable($class)));
        self::assertEquals($object5, iterator_to_array(InlineObject::fromSerializable($class)));

        // not JSON5 Serailizable
        self::assertEquals($object, iterator_to_array(ArrayValue::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactArray::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineArray::fromJsonSerializable($class)));

        self::assertEquals($object, iterator_to_array(ObjectValue::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(CompactObject::fromJsonSerializable($class)));
        self::assertEquals($object, iterator_to_array(InlineObject::fromJsonSerializable($class)));
    }
}
Loading